Каковы этапы разработки компилятора?
Компилятор работает в разные фазы, каждая фаза преобразует исходную программу из одного представления в другое. Каждая фаза принимает входные данные от своей предыдущей стадии и передает свои выходные данные следующей фазе компилятора.
В компиляторе 6 фаз. Каждый из этих этапов помогает преобразовать язык высокого уровня в машинный код. Фазы компилятора:
- Лексический анализ
- Синтаксический анализ
- Семантический анализ
- Генератор промежуточного кода
- Оптимизатор кода
- Генератор кода
На всех этих этапах исходный код преобразуется путем разделения на токены, создания деревьев синтаксического анализа и оптимизации исходного кода по разным этапам.
В этом руководстве вы узнаете:
- Каковы этапы разработки компилятора?
- Этап 1: лексический анализ
- Этап 2: синтаксический анализ
- Фаза 3: семантический анализ
- Этап 4: Генерация промежуточного кода
- Этап 5: Оптимизация кода
- Фаза 6: Генерация кода
- Управление таблицей символов
- Процедура обработки ошибок:
Этап 1: лексический анализ
Лексический анализ - это первый этап, на котором компилятор просматривает исходный код. Этот процесс можно выполнять слева направо, символ за символом, и группировать эти символы в токены.
Здесь поток символов из исходной программы сгруппирован в значимые последовательности путем идентификации токенов. Он вносит соответствующие билеты в таблицу символов и передает этот токен на следующую фазу.
Основные функции этого этапа:
- Определите лексические единицы в исходном коде
- Классифицируйте лексические единицы по классам, таким как константы, зарезервированные слова, и введите их в разные таблицы. Комментарии в исходной программе игнорируются.
- Определите токен, который не является частью языка
Пример :
х = у + 10
Жетоны
Икс | идентификатор |
знак равно | Оператор присваивания |
Y | идентификатор |
+ | Оператор сложения |
10 | Число |
Этап 2: синтаксический анализ
Анализ синтаксиса - это поиск структуры кода. Он определяет, соответствует ли текст ожидаемому формату. Основная цель этого этапа - убедиться, что исходный код был написан программистом правильно или нет.
Синтаксический анализ основан на правилах, основанных на конкретном языке программирования, путем построения дерева синтаксического анализа с помощью токенов. Он также определяет структуру исходного языка и грамматику или синтаксис языка.
Вот список задач, выполняемых на этом этапе:
- Получить токены из лексического анализатора
- Проверяет синтаксически правильное выражение
- Сообщать обо всех синтаксических ошибках
- Создайте иерархическую структуру, известную как дерево синтаксического анализа.
Пример
Любой идентификатор / номер - это выражение
Если x - идентификатор, а y + 10 - выражение, тогда x = y + 10 - это утверждение.
Рассмотрим дерево синтаксического анализа для следующего примера
(a+b)*c
В дереве синтаксического анализа
- Внутренний узел: запись с полем оператора и два файла для детей
- Лист: записи с 2-мя и более полями; один для токена и другая информация о токене
- Убедитесь, что компоненты программы осмысленно сочетаются друг с другом.
- Собирает информацию о типах и проверяет совместимость типов
- Проверочные операнды разрешены исходным языком
Фаза 3: семантический анализ
Семантический анализ проверяет семантическую непротиворечивость кода. Он использует синтаксическое дерево предыдущего этапа вместе с таблицей символов, чтобы убедиться, что данный исходный код является семантически непротиворечивым. Он также проверяет, передает ли код соответствующее значение.
Semantic Analyzer проверит несоответствие типов, несовместимые операнды, функцию, вызванную с неправильными аргументами, необъявленную переменную и т. Д.
Функции этапа семантического анализа:
- Помогает вам хранить собранную информацию о типах и сохранять ее в таблице символов или синтаксическом дереве.
- Позволяет выполнять проверку типа
- В случае несоответствия типов, когда нет точных правил исправления типа, которые удовлетворяют желаемой операции, отображается семантическая ошибка.
- Собирает информацию о типе и проверяет совместимость типов
- Проверяет, разрешает ли исходный язык операнды или нет
Пример
float x = 20.2;float y = x*30;
В приведенном выше коде семантический анализатор преобразует целое число 30 в число с плавающей запятой 30.0 перед умножением.
Этап 4: Генерация промежуточного кода
После завершения этапа семантического анализа компилятор генерирует промежуточный код для целевой машины. Он представляет собой программу для некоторой абстрактной машины.
Промежуточный код находится между языком высокого уровня и языком машинного уровня. Этот промежуточный код необходимо сгенерировать таким образом, чтобы его можно было легко перевести в целевой машинный код.
Функции генерации промежуточного кода:
- Он должен быть сгенерирован из семантического представления исходной программы.
- Содержит значения, вычисленные в процессе перевода.
- Помогает перевести промежуточный код на целевой язык
- Позволяет поддерживать порядок приоритета исходного языка
- Он содержит правильное количество операндов инструкции
Пример
Например,
total = count + rate * 5
Промежуточный код с помощью метода адресного кода:
t1 := int_to_float(5)t2 := rate * t1t3 := count + t2total := t3
Этап 5: Оптимизация кода
Следующим этапом является оптимизация кода или промежуточный код. На этом этапе удаляется ненужная строка кода и упорядочивается последовательность операторов, чтобы ускорить выполнение программы без потери ресурсов. Основная цель этого этапа - улучшить промежуточный код для создания кода, который работает быстрее и занимает меньше места.
Основные функции этого этапа:
- Это поможет вам найти компромисс между скоростью выполнения и компиляции.
- Улучшает время работы целевой программы
- Создает оптимизированный код все еще в промежуточном представлении
- Удаление недостижимого кода и избавление от неиспользуемых переменных
- Удаление не измененных операторов из цикла
Пример:
Рассмотрим следующий код
a = intofloat(10)b = c * ad = e + bf = d
Может стать
b =c * 10.0f = e+b
Фаза 6: Генерация кода
Генерация кода - это последняя и последняя фаза компилятора. Он получает входные данные на этапах оптимизации кода и в результате создает код страницы или объектный код. Цель этого этапа - выделить память и сгенерировать перемещаемый машинный код.
Он также выделяет ячейки памяти для переменной. Инструкции в промежуточном коде преобразуются в машинные команды. На этом этапе код оптимизации или промежуточный код переводится на целевой язык.
Целевой язык - машинный код. Следовательно, все ячейки памяти и регистры также выбираются и распределяются на этом этапе. Код, сгенерированный на этом этапе, выполняется, чтобы принимать входные данные и генерировать ожидаемые выходные данные.
Пример:
а = Ь + 60,0
Возможно будет переведено в регистры.
MOVF a, R1MULF #60.0, R2ADDF R1, R2
Управление таблицей символов
Таблица символов содержит запись для каждого идентификатора с полями для атрибутов идентификатора. Этот компонент упрощает компилятору поиск записи идентификатора и ее быстрое извлечение. Таблица символов также помогает вам в управлении объемом. Таблица символов и обработчик ошибок взаимодействуют со всеми фазами, и таблица символов обновляется соответственно.
Процедура обработки ошибок:
В процессе проектирования компилятора ошибка может возникнуть на всех этапах, указанных ниже:
- Лексический анализатор: неправильно написанные токены
- Анализатор синтаксиса: отсутствуют круглые скобки
- Генератор промежуточного кода: несоответствующие операнды для оператора
- Оптимизатор кода: когда оператор недоступен
- Генератор кода: недостижимые утверждения
- Таблицы символов: ошибка нескольких объявленных идентификаторов
Наиболее распространенными ошибками являются недопустимая последовательность символов при сканировании, недопустимые последовательности маркеров в типе, ошибка области действия и синтаксический анализ в семантическом анализе.
Ошибка может возникнуть на любом из вышеуказанных этапов. После обнаружения ошибок фаза должна обработать ошибки, чтобы продолжить процесс компиляции. Об этих ошибках необходимо сообщить обработчику ошибок, который обрабатывает ошибку для выполнения процесса компиляции. Как правило, об ошибках сообщается в виде сообщения.
Резюме
- Компилятор работает на разных этапах, каждый этап преобразует исходную программу из одного представления в другое.
- Шесть этапов проектирования компилятора: 1) Лексический анализ 2) Синтаксический анализ 3) Семантический анализ 4) Генератор промежуточного кода 5) Оптимизатор кода 6) Генератор кода
- Лексический анализ - это первый этап, на котором компилятор просматривает исходный код.
- Синтаксический анализ - это поиск структуры текста
- Семантический анализ проверяет семантическую непротиворечивость кода
- Как только этап семантического анализа завершится компилятором, сгенерируйте промежуточный код для целевой машины.
- Этап оптимизации кода удаляет ненужную строку кода и упорядочивает последовательность операторов
- Фаза генерации кода получает входные данные из фазы оптимизации кода и в результате создает код страницы или объектный код.
- Таблица символов содержит запись для каждого идентификатора с полями для атрибутов идентификатора.
- Подпрограмма обработки ошибок обрабатывает ошибки и отчеты на многих этапах