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

компилятор ТСС. 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
страница14 из 38
1   ...   10   11   12   13   14   15   16   17   ...   38
static void parse_expr_type(CType *type) Пропускется '('. Вызывается parse_btype() если он вернул ненулевое значение, вызывается type_decl() иначе expr_type() Пропускается ')' static void struct_decl(CType *type, int u) Текущий токен сохраняется в о верменной переменной a. Вызывается next(). Если текущий токен это не '{' то происходят следующие действия: Токен сохраняется во временной переменной v, вызывается next(). Если токен является зарегистрированым, компилятор завершается с ошибкой. Для v ишется Sym с помощью struct_find(). Если поле t структуры CType связанной с найденным символом не равен a, компилятор завершается с ошибкой. Если символ найден и поле ссответствует, происходит переход на do_decl. Если проверка на равенсво '{' дала положительный результат, то v присваивается увеличенное значение anon_sym. Поле t временной структуры CType обновляется значением a Формируется символ с помощью sym_push(). Его поле r отвечающее за связь с регисром обнуляется. Начиная с метки do_decl приходят следующие действия: В переданом CType заполняются поля t и ref в первое записывается значение записывается переданное значение VT_ENUM или VT_STRUCT. Во сторое ссылка на созданный символ. Если текущий токен это '{', то получается следующий с помощью next(). Если поле символа, указывающее на число содержит значение отличное от -1, компилятор завершается с ошибкой. Временное число сбрасывется в ноль Если сохраненный в a токен равен TOK_ENUM. В бесконечном цикле сохраняется текущий токен в v. Если он является зарегистрированным, компилятор завершается с ошибкой. Получаем следующий токен. Если он равен '=', получаем еще один токен и вызываем expr_const() чтобы получить числовое значение. Полученное значение передается на выход sym_push(). Символ окажется в стеке и мы получим на него ссылку. По ней мы получим связанный CType и в его поле t установим бит VT_STATIC Если текущий токен отличен от ',', бесконечный цикл прекращается. Иначе получаем еще один токен и увеличиваем числовое значение. Если полученный токен это '}', прекращаем цикл. Вызывается skip() чтобы пропустить '}' Если сохраненный в a токен не равен TOK_ENUM. Начинается бесконечный цикл пока не встретится токен '}' Вызывается parse_btype() и начинается бесконечный цикл Если текущий токен не равен ':', вызывается type_decl(). Если эта функция сбрасывает v в 0 и в поле t переданного CType не устанавливает VT_STRUCT, компилятор завершается с ошибкой. Если в поле t переданного CType установлен бит VT_FUNC или установлен один из бит VT_TYPEDEF, VT_STATIC, VT_EXTERN или VT_INLINE, компилятор завершается с ошибкой. Если текущий тоне равен ':', получаем следующий токен, вызываем expr_const(), она разбирает константу и возвращает ее значение. Если оно меньше нуля, компилятор завершается с ошибкой. Если значение равно нулю, но при этом v присвоено значение, компилятор завершается с ошибкой. Вызывается type_size(), который возвращает размер типа и изменяет переданный ей параметр align Переменная типа AttributeDef измененная функцией type_decl() имеет поле aligned Если это поле содержит значение то, при необходимости, align увеличивается до этого значения. Если поле aligned содержит нулевое значение, проверяется поле packed, если оно установлено, align присваивается 1 Если оба поля не содержат значение, проверяется pack_stack_ptr текущего значение. Если оно установлено, то align сравнивается с его значением и при необходимости уменьшается до него. Если bit_size (значение константы) больше нуля, проверяются установленны ли биты кодирующие целочисленные типы в поле t. Если установлен хотябы один, компилятор завершается с ошибкой. В bsize записывается размер типа умноженный на 8. Это значение сравнивается со значением константы. Если обнаружено превышение, компилятор завершается с ошибкой. Если полученные значения равны, bit_pos обнулятся. Если размер типа равен нулю а bit_pos на предыдущих шагах цикла получил значение, то его значение обновляется значением bsize Если bit_size не равна нулю, не превышает и не равен bsize, происходят следующие действия: Если сумма bit_pos и bit_size больше bsize, bit_pos обнуляется. lbit_pos обновляется значением bit_pos В поле t временного CType устанавливаются биты CType и биты в позициях bit_pos и bit_size. К позиция добавляются необходимые сдвиги. bit_pos увеличивается на bit_size Если bit_size меньше нуля, bit_pos обнуляется. Если v была изменена и в поле t временного CType установлен бит VT_STRUCT, происходят следующие действия: Если lbit_pos равен нулю: a проверяется на равенство TOK_STRUCT. Числовое значение увеличивается на align — 1 Лишние биты в числовом значении отбрасываются с помощью побитового И с -align offset обновляется числовым значением. Если size больше нуля, числовое значение увеличивается на size Если a не равен TOK_STRUCT, offset обнуляется, если size больше нуля, числовое значение обновляется значением size Если align больше maxalign, maxalign увеличивается до соответствующего размера. Если v осталась равной нулю и в поле t временного CType установлен бит VT_STRUCT, происходят следующие действия: По полю ref временного CType происходит обход символов и для каждго вызывается sym_push(), чтобы добавить поля структуры с соответствущим смещением. Указатель на символ сдвигается вперед. Если предыдущее условие не сработало но v было изменено, вызывается sym_push() чтобы добавить соответствущее знечение. Указатель на символ сдвигается вперед. Если встречается токен ';' или TOK_EOF, бесконечный цикл прерываетя. Вызывается skip() чтобы пропустить ';' Вызывается skip() чтобы пропустить '}' У символ структуры обновляются поля c и r. Они хранят размер и выравнивание структуры.
1   ...   10   11   12   13   14   15   16   17   ...   38


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