
- •Глава 1. Введение 2
- •Глава 2. Лексический анализ 6
- •2.4. Построение детерминированного конечного
- •Глава 3. Синтаксический анализ 20
- •Глава 8. Генерация кода 76
- •Глава 9. Системы автоматизации построения трансляторов 120
- •Глава 1. Введение
- •1.1. Место компилятора в программном обеспечении
- •1.2. Структура компилятора
- •Глава 2. Лексический анализ
- •2.1. Регулярные множества и регулярные выражения
- •2.2. Конечные автоматы
- •2.5. Программирование лексических анализаторов
- •2.6. Конструктор лексических анализаторов lex
- •Глава 3. Синтаксический анализ
- •3.1. Основные понятия и определения
- •3.2. Таблично-управляемый предсказывающий разбор
- •3.2.1. Алгоритм разбора сверху-вниз
- •3.2.2. Множества first и follow.
- •3.2.4. Ll(1)-грамматики
- •3.2.5. Удаление левой рекурсии
- •3.2.6. Левая факторизация
- •3.2.7. Рекурсивный спуск
- •3.2.8. Диаграммы переходов для рекурсивного спуска
- •3.2.9. Восстановление после синтаксических ошибок
- •3.3. Разбор снизу-вверх типа сдвиг-свертка
- •3.3.1. Основа
- •3.3.2. Lr(k)-анализаторы
- •3.3.4. Конфликты разбора типа сдвиг-свертка
- •3.3.5. Восстановление после синтаксических ошибок
- •Глава 4. Промежуточные представления программы
- •4.1. Представление в виде ориентированного графа
- •4.2. Трехадресный код
- •4.3. Линеаризованные представления
- •4.4. Организация информации в генераторе кода
- •4.5. Уровень промежуточного представления
- •Глава 5. Элементы теории перевода
- •5.1. Преобразователи с магазинной памятью
- •5.2. Синтаксически управляемый перевод
- •5.3. Атрибутные грамматики
- •5.3.1. Определение атрибутных грамматик
- •5.3.2. Атрибутированное дерево разбора
- •5.3.3. Язык описания атрибутных грамматик
- •Глава 6. Контекстные условия языков программирования
- •6.1. Описание областей видимости и блочной структуры
- •6.2. Структура среды Модулы-2
- •6.3. Занесение в среду и поиск объектов
- •Глава 7. Организация таблиц символов компилятора
- •7.1. Таблицы идентификаторов и таблицы символов
- •7.2. Таблицы идентификаторов
- •7.3. Таблицы символов и таблицы расстановки
- •7.4. Функции расстановки.
- •7.5. Таблицы на деревьях
- •7.7. Сравнение различных методов реализации таблиц
- •Глава 8. Генерация кода
- •8.1. Модель машины
- •8.2. Динамическая организация памяти
- •8.3. Назначение адресов
- •8.4. Трансляция переменных.
4.4. Организация информации в генераторе кода
Чисто синтаксическое дерево несет только информацию о структуре
программы. На самом деле в процессе генерации кода требуется также
информация о переменных (например, их адреса), процедурах (также
адреса, уровни), метках и т.д. Для представления этой информации
возможны различные решения. Наиболее распространены два. 1) всю эту
информацию можно хранить в таблицах генератора кода; 2) информация
хранится в вершинах дерева с соответствующими указателями.
Рассмотрим, например, структуру таблиц, которые могут быть
использованы в сочетании с Лидер-представлением. Поскольку
Лидер-представление не содержит информации об адресах переменных,
значит, эту информацию нужно формировать в процессе обработки
объявлений и хранить в таблицах. Это касается и описаний массивов,
записей и т.д. Кроме того, в таблицах также должна содержаться
информация о процедурах (адреса, уровни, модули, в которых процедуры
описаны, и т.д.). Таким образом структура таблиц может быть такой, как
это изображено на рис. 4.9.
Таблица уровней Таблица описаний
процедур
+-----+ +----------------------------+
| --+--------+ |Для типа:размер |
|-----| | |----------------------------|
| --+----+ | |Для переменной:указатель на |
| ....|.. | | |тип и адрес (смещение) |
|-----| | | |----------------------------|
| --+--+ | +-->|Для процедуры: адрес, ... |
+-----+ | | |----------------------------|
| +--> |............................|
| | |
| |----------------------------|
+-------->| |
+----------------------------+
Рис. 4.9
При входе в процедуру в таблице уровней процедур заводится новый
вход - указатель на таблицу описаний. При выходе указатель
восстанавливается на старое значение. Если промежуточное представление
- дерево, то информация может храниться в вершинах самого дерева.
Например, та же информация может быть представлена, как на рис. 4.10.
/\
/ \
/ \
/ \
/ \
Раздел описаний / \
/ \ \
/ \ \
/ \ \
Описание Описание Раздел
типа переменной операторов
+--------+ +--------+ +------+
| |<--+--- |<----------+--- |
+--------+ +--------+ +------+
Рис. 4.10
4.5. Уровень промежуточного представления
Как видно из приведенных примеров, промежуточное представление
программы может в различной степени быть близким либо к исходной
программе, либо к машине. Например, промежуточное представление может
содержать адреса переменных, и тогда оно уже не может быть перенесено
на другую машину. С другой стороны, промежуточное представление может
содержать раздел описаний программы, и тогда информацию об адресах
можно извлечь из обработки описаний. В то же время ясно, что первое
более эффективно, чем второе.
Операторы управления в промежуточном представлении могут быть
представлены в исходном виде (в виде операторов языка if, for, while и
т.д.), а могут содержаться в виде переходов. В первом случае некоторая
информация может быть извлечена из самой структуры (например, для
оператора for - информация о переменной цикла, которую, может быть,
разумно хранить на регистре, для оператора case - информация о таблице
меток и т.д.). Во втором случае представление проще и унифицированней.
Некоторые формы промежуточного представления лучше годятся для
различного рода оптимизаций (например, косвенные тройки - для
перемещения кода), некоторые - хуже (например, префиксная запись для
этого плохо подходит).