Дизайн компилятора - этапы компиляции
Процесс компиляции представляет собой последовательность различных этапов. Каждая фаза принимает входные данные из своей предыдущей стадии, имеет собственное представление исходной программы и передает свои выходные данные следующей фазе компилятора. Давайте разберемся с этапами компилятора.
Лексический анализ
Первая фаза сканера работает как сканер текста. На этом этапе исходный код сканируется как поток символов и преобразуется в значимые лексемы. Лексический анализатор представляет эти лексемы в виде токенов как:
<token-name, attribute-value>
Синтаксический анализ
Следующий этап называется синтаксическим анализом или parsing. Он принимает токен, полученный в результате лексического анализа, в качестве входных данных и генерирует дерево синтаксического анализа (или дерево синтаксиса). На этом этапе компоновка токенов проверяется на соответствие грамматике исходного кода, т. Е. Синтаксический анализатор проверяет синтаксически правильное выражение, созданное токенами.
Семантический анализ
Семантический анализ проверяет, соответствует ли построенное дерево синтаксического анализа правилам языка. Например, присвоение значений осуществляется между совместимыми типами данных и добавлением строки к целому числу. Также семантический анализатор отслеживает идентификаторы, их типы и выражения; объявлены ли идентификаторы перед использованием или нет и т. д. Семантический анализатор выдает аннотированное синтаксическое дерево в качестве вывода.
Генерация промежуточного кода
После семантического анализа компилятор генерирует промежуточный код исходного кода для целевой машины. Он представляет собой программу для некоторой абстрактной машины. Он находится между языком высокого уровня и машинным языком. Этот промежуточный код должен быть сгенерирован таким образом, чтобы облегчить его перевод в целевой машинный код.
Оптимизация кода
На следующем этапе выполняется оптимизация кода промежуточного кода. Оптимизация может рассматриваться как что-то, что удаляет ненужные строки кода и упорядочивает последовательность операторов, чтобы ускорить выполнение программы без потери ресурсов (ЦП, память).
Генерация кода
На этом этапе генератор кода берет оптимизированное представление промежуточного кода и отображает его на целевой машинный язык. Генератор кода переводит промежуточный код в последовательность (обычно) перемещаемого машинного кода. Последовательность инструкций машинного кода выполняет задачу так же, как и промежуточный код.
Таблица символов
Это структура данных, поддерживаемая на всех этапах работы компилятора. Здесь хранятся все имена идентификаторов вместе с их типами. Таблица символов упрощает компилятору быстрый поиск записи идентификатора и ее получение. Таблица символов также используется для управления объемом.