- •Формальные грамматики и языки.
- •Задача разбора
- •Классификация грамматик по Холмскому.
- •Диаграмма состояний
- •Отношения предшествования
- •Распознаватель
- •Матрица предшествования
- •Некоторые приемы приведения к грамматикам простого предшествования.
- •Представление автоматов.
- •Концевые маркеры и выходы из распознавания.
- •Эквивалентность состояний.
- •Проверка эквивалентности двух состояний.
- •Недостижимые состояния.
- •Алгоритм составления списка достижимых состояний.
- •Приведённые автоматы.
- •Получение минимального автомата.
- •Недетерминированные автоматы.
- •Эквивалентность недетерминированных и детерминированных конечных распознавателей (нкр и дкр).
- •Задание:
- •Транслятор.
- •Введение таблицы символов.
- •Включение неявной информации.
- •Обнаружение ошибок.
- •Макрообработка и операции, выполняемые во время компиляции.
- •Синтез объектной программы.
- •Оптимизация.
- •Генерация кода.
- •Редактирование связей и загрузки.
- •Задача идентификации. Реализация ка при работе трансляторов.
- •Хранение информации о лексемах.
- •Механизм запоминания.
- •Метод хеширования.
- •Нисходящий разбор с возвратами.
- •Начальная установка.
- •Новый человек.
- •Неудача
- •Класс грамматик, допускающих нисходящий распознаватель.
- •Статистические управляемые схемы перевода и атрибутные грамматики.
- •Контекстные условия
Синтез объектной программы.
Заключительная стадия трансляции отводится под построение выполняемой программы из той, которую выдаёт семантический анализатор. Эта фаза обязательно включает генерацию кода и может также включать оптимизацию полученной программы. Если подпрограммы транслировались отдельно или использовалась библиотека подпрограмм, то необходима заключительная стадия редактирования связей и загрузки, чтобы получить программу, пригодную для выполнения.
Оптимизация.
На выходе семантического анализатора обычно получается странслированная выполняемая программа, представления в некоторой внутренней форме, такой, как польская цепочка операций и операндов или таблица из последовательностей операций и операндов. Из этого внутреннего представления генераторы кода могут породить выходной объективный код в соответствующем формате. Однако, обычно ещё до генерации кода производится та или иная оптимизация программы в её внутреннем представлении. Для семантического анализатора типично порождение внутренней программы по частям, как если бы анализировался каждый кусок исходной программы. Эта задача существенно проще, если семантическому анализатору безразличны соседние команды, которые генерировались непосредственно перед этим. Но такая касочная трансляция может привести к чрезвычайно неэффективной программе: например, регистр, который может запоминаться в конце одного генерированного сегмента, немедленно перезагружается из той же самой ячейки в начало следующего сегмента. Часто бывает желательно позволить семантическому анализатору строить такие убогие последовательности команд, чтобы затем на стадии оптимизации заменить их другими, свободными от очевидной неэффективности.
Многие компиляторы не ограничиваются такого сорта простой оптимизации и анализирует программу ради других возможных усовершенствований: однократное вычисление общих подвыражений, вынесение инвариантных операций за пределы цикла, оптимизация использования регистров. Вопросы оптимизации программ исследовались довольно глубоко.
Генерация кода.
Эта стадия проста. Программа, странслированная во внутренние представление, уже оптимизирована и теперь нужно только превратить её в инструкции языка ассемблера, либо в машинный код, либо в какой-либо иной объектный код, который и будет результатом трансляции. При этом, информацию, содержащуюся во внутреннем представлении программы, нужно привести к соответствующему формату. Код, полученный на выходе, или будет пригоден для выполнения, или должен быть передан на другую стадию трансляции, например ассемблирование или редактирование связей и загрузку.
Редактирование связей и загрузки.
В этой необязательной заключительной стадии трансляции куски программы, полученные как отдельно транслированные подпрограммы, объединяются в выполняемую программу в её окончательном виде. Выполняемые программы, полученные на предыдущих фазах трансляции, обычно имеют почти окончательный вид, за исключением тех мест, где программы обращаются к внешним данным или другим подпрограммам. Связи между этими разрозненными кусками программы указываются в таблицах загрузчика, выданных транслятором. Загрузчик разрешает связи, вставляет адреса подпрограмм и данные. В результате получается программа, пригодная для прогона.
