Компилятор, для того, чтобы получить исходный exe файл должен пройти несколько этапов.
Входной текст
--> Лексический анализ
--> Синтаксический анализ
--> Семантический анализ
--> Генерация промежуточного кода
--> Оптимизация промежуточного кода
--> Генерация машинного кода.
Все это связано с Диспетчером таблицы символов и обработки ошибок.
Лексический анализ
Лексический анализ – разбивает входной текст программы на лексемы. Лексемы – это ключевые слова, идентификаторы, разделители и т. д. На стадии лексического анализа убираются пробелы и комментарии. Результаты работы лексического анализа является последовательность кода лексем.
vhile i < 0
Это не будет ошибка на стадии лексического анализа.
маша i < 0
На стадии лексического анализа выйдет ошибка на недопустимые символы.
a = b + c*60;
В результате лексического анализа будет выделено:
Лексема |
код |
Примечание |
a |
1 |
id1 |
= |
2 |
id2 |
b |
3 |
id3 |
+ |
4 |
id4 |
c |
5 |
id5 |
* |
6 |
id6 |
60 |
7 |
id7 |
; |
8 |
id8 |
Синтаксический анализ
Синтаксический анализ определяет порядок следования лексем и переводит входной текст в некое промежуточное представление, позволяющее учитывать приоритеты операций.
Например: синтаксическое дерево, польская запись и др.
Данное дерево обходит синтаксический анализатор с низу в верх или с верху вниз.
Семантический анализ
Семантический анализ – это проверка смысла, обращение к процедурам и функциям. Пример: присваивать имя процедуры нельзя (в языке Паскаль). Проверка совместимости типов и их преобразование.
В языке Си используется перегрузка функция, поэтому проходит проверка на этом этапе.
Есть ограничение на определенные конструкции. Например, идентификатор массива должен быть только целого типа. На этом этапе проходит проверка.
Проверка управления. Например, проверка оператора break.
Проверка единственности: В некоторых языках переменную можно определять только один раз.
Проверки, связанные с именами.
Диспетчер таблицы символов.
Может быть массивом записей, списком записей, наибольшее распространение получила ХЕШ таблица. Содержит имя идентификатора и ссылку на его атрибуты: тип, область видимости, адреса и так далее. ХЕШ таблица позволяет увеличить скорость доступа к идентификатору, обнаружение ошибок и сообщение о них.
На стадии семантического, определяется ошибки семантики, перечисленные выше.
Генерация промежуточного кода
t1=int toreal(60)
t2 = t1*c
t3= b+ t2
a = t3
for(i=1; i<n; i++)
{a[i] = b[i];}
При распараллеливании вот этот цикл можно записать следующим образом:
for(i=1; i<n; i+=2)
{a[i] = b[i]; a[i+1] = b[i+1];}
Удаление мертвого кода. Например: переменные, которые не используются.
Замена на другие операции:
c = a*4;
Можно заменить на:
c = a shl 2;
При работе со строковыми переменными: при копировании строки, копируется ссылка, а не данные.
Генерация машинного кода
Преобразование исходного кода на язык ассемблер.
MOVF AX, #60
MOVF BX, C
MULF AX, BX
MOVF BX, b
ADDF AX, BX
MOVF a, AX