Главная страница

компилятор ТСС. Tiny c compiler by Fabrice Bellard Описание алгоритмов


Скачать 191.99 Kb.
НазваниеTiny c compiler by Fabrice Bellard Описание алгоритмов
Анкоркомпилятор ТСС
Дата08.11.2019
Размер191.99 Kb.
Формат файлаodt
Имя файлаtcc book.odt
ТипДокументы
#94047
страница9 из 38
1   ...   5   6   7   8   9   10   11   12   ...   38
static int *macro_arg_subst(Sym **nested_list, int *macro_str, Sym *args) Инициализируются поля экземпляра структуры TokenString с помощью tok_str_new(), Временная переменная last_tok инициализируется нулевым значением. Бесконечный цикл начинается с функции TOK_GET() и останавливается, если этот макрос запишет во временную переменную нулевой код токена. Если это токен '#': Получем еще один токен с помощью TOK_GET(). Продолжаем выполненеие, если удалось получить токен. Сущность ищется в цепочке args с помощю sym_find2(). Экземпляр структуры CString заполняется нулями с помощью cstr_new(). Флаг notfirst сбрасывается, пока по временному указателю получено ненулевое значение. Этот указатель сдвигатеся с помощью TOK_GET(), а полученный с помощь этой фунции токен превращается в строку с помощью get_tok_str(). И полученная строка добавляется в итоговую строку с помощю cstr_cat(). Тем же способом на первом шаге в итоговую строку в самое начало добавляется пробел. Флаг notfirst устанавливается если флаг препроцессора PP_NOSPACES включен, чтобы пробелы на следующих шагах не добалялись. Когда данные по временному укзателю больше не поступают в конец итоговой сроки добваляется нулевой символ. В поле cstr экземпляр структуры CValue записывается адрес итоговой строки. Этот экземплят структуры записывется с структуру TokenString с помощью tok_str_add2() с типом TOK_STR. Временных экземпляр CValue очищается с помощью cstr_free() Если sym_find2() при предидущей проверке не нашла в args указанный токен, то он просто добавляется, то он просто доваляестя в структуру TokenString с помощью tok_str_add2(). Если полученный токен это не '#', то его код сравнивается с TOK_IDENT и если он больше указанного занчения, это не службнаяная сущность. Она обрабатывается следующим образом: Токен ищется в цепочке args c помощью sym_find2(). Если удалось найти сущность: Поручаем указатель на ее поле, указвающее на число сохраняем в переменной st. Если токен по указателю macro_str это TOK_TWOSHARPS или это значение сохранено в переменной last_tok, присходит следующая обработка: Если установлен флаг gnu_ext, поле type найденной сущности имеет ненулевое поле типа, TOK_TWOSHARPS сохранена в last_tok, длинна строки больше или рана двум и предпоследний символ в строке запяная ',', то в зависимости от числа полученного по указателю st. Если это 0, поле отвечающее за длину уменьшается на 2 байта, в другом слуые на 1 байт, а упраление передается на метку add_var. Если флаг gnu_ext сброшен или не выполняется одно из других упомянутых условий, то из указателя st с помощю TOK_GET() получаются все доступные токены и добавляются в строку с помощью tok_str_add2(); Если sym_find2() не находи сущность для токена, то он просто добавляется в строку с помощью tok_str_add2() На каждом шаге бесконечного цикла значение last_tok обноляется текущим токеном. После окончания цикла в строку добаляется завершающий нулевой символ. static void macro_subst(TokenString *tok_str, Sym **nested_list, const int *macro_str, struct macro_level ** can_read_stream) В переданной строка обрабатываются символы довойных решеток с помощь macro_twosharps(). Если эта фунция возвращает нулевой указатель, то используемый указатель (переменная ptr) обноляется изначально переданным указателем. Как только сдвиг указателя приведет к тому, что он станет нулевым бесконечный цикл прервется. Из текущего указателя получем токен с помощью TOK_GET(). Если поучаем нулевой код прекращаем обработку. С помощью define_find() осуществляется поиск сущности. Если возвращен ненулевой указатель, о токен ищется в nested_list с помощью sym_find2(). Если сущность найдена управление передается на метку no_subst В поле адреса значения текущей структуры macro_level записывается текущее значение глобального указателя macro_ptr Если указатель can_read_stream содержит ненулевое значения, в цепочку структур macro_level добавляется этот указатель. Глобальный указатель macro_ptr обновляется значением указателя ptr. Текущий глобальный токен (переменная tok) обновляется значением текущего обрабатываемого токена. Вызывается macro_subst_tok() и ее результат сохраняется во верменной переменной ret Переменной ptr присваивается macro_ptr, а сам macro_ptr обновляется адресом из поля адреса текущей структуры macro_level Если адрес can_read_stream указывает на текущую структуру macro_level, то текущая структура сдвигатся на одну позицию назад. Если в перемнной ret сохранился не нулевой результат macro_subst_tok(), то упраление передается на метку no_subst Если define_find() вернул нулевое значение начинается блок с меткой no_subst. Он заключается в добавлении текущего токена в строку с помощью tok_str_add2()

Если macro_twosharps() изменила передаваемый ей указатель, то для него вызывается tok_str_free().
1   ...   5   6   7   8   9   10   11   12   ...   38


написать администратору сайта