
- •Содержание
- •Введение
- •1.3. Множества цепочек
- •1.4. Языки
- •1.5. Алгоритмы
- •1.6. Некоторые понятия теории графов
- •Контрольные вопросы
- •2. Введение в компиляцию
- •2.1. Задание языков программирования
- •2.2. Синтаксис и семантика
- •2.3. Процесс компиляции
- •2.4. Лексический анализ
- •2.5. Работа с таблицами
- •Переменная с плавающей точкой
- •2.6. Синтаксический анализ
- •2.7. Генератор кода
- •2.8. Оптимизация кода
- •2.8. Оптимизация кода
- •2.9. Исправление ошибок
- •2.10. Резюме
- •Контрольные вопросы
- •3. Теория языков
- •3.1. Способы определения языков
- •3.2. Грамматики
- •3.4. Распознаватели
- •3.5. Регулярные множества, их распознавание и порождение
- •5.2. LR(1) - таблица разбора
- •5.3. Построение LR – таблицы разбора
- •5.4. Сравнение LL – и LR – методов разбора
- •Контрольные вопросы
- •6. Оптимизация кода
- •6.1. Оптимизация линейного участка
- •6.1.1. Модель линейного участка
- •6.1.2. Преобразование блока
- •6.1.3. Графическое представление блоков
- •6.1.4. Критерий эквивалентности блоков
- •6.1.5. Оптимизация блоков
- •6.1.6. Алгебраические преобразования
- •6.2. Арифметические выражения
- •6.2.1. Модель машины
- •6.2.2. Разметка дерева
- •6.2.3. Программы с командами STORE
- •6.2.4. Влияние некоторых алгебраических законов
- •6.3. Программы с циклами
- •6.3.1. Модель программы
- •6.3.2. Анализ потока управления
- •Алгоритм вычисления прямого доминирования
- •6.3.3. Примеры преобразования программ
- •Удаления бесполезных операторов
- •Замена сложных операций
- •6.3.4. Оптимизация циклов
- •Перемещение кода
- •Индуктивное перемещение
- •Замена сложных операций
- •6.4. Анализ потоков данных
- •6.4.1. Интервалы
- •6.4.2. Анализ потоков данных с помощью интервалов
- •6.4.3. Несводимые графы управления
- •7. Включение действий в синтаксис
- •7.1. Получение четверок
- •7.2. Работа с таблицей символов
- •Контрольные вопросы
- •8. Проектирование компиляторов
- •8.1. Число проходов
- •8.2. Таблицы символов
- •8.3. Таблица видов
- •Контрольные вопросы
- •9. Распределение памяти
- •9.1. Стек времени прогона
- •9.2. Методы вызова параметров
- •9.3. Обстановка выполнения процедур
- •9.4. «Куча»
- •9.5. Счетчик ссылок
- •9.6. Сборка мусора
- •Контрольные вопросы
- •10. Генерация кода
- •10.1. Генерация промежуточного кода.
- •10.2. Структура данных для генерации кода
- •10.3. Генерация кода для типичных конструкций
- •10.3.1. Присвоение
- •10.3.2. Условные зависимости
- •10.3.3. Описание идентификаторов
- •10.3.4. Циклы
- •10.3.5. Вход и выход из блока
- •10.3.6. Прикладные реализации
- •10.4. Проблемы, связанные с типами
- •10.5. Время компиляции и время прогона
- •Контрольные вопросы
- •11. Исправление и диагностика ошибок
- •11.1. Типы ошибок
- •11.2. Лексические ошибки
- •11.3. Ошибки в употреблении скобок
- •11.4. Синтаксические ошибки
- •11.5. Методы исправления синтаксических ошибок
- •11.6. Предупреждения
- •11.7. Сообщения о синтаксических ошибках
- •11.8. Контекстно-зависимые ошибки
- •11.9. Ошибки, связанные с употреблением типов
- •11.10. Ошибки, допускаемые во время прогона
- •Контрольные вопросы
- •Список литературы
39
Таблица 2.3 - Оптимизация кода
LOAD |
=0.98 |
LOAD |
=0.98 |
LOAD |
TAX |
STORE |
$2 |
STORE |
$2 |
ADD |
PRICE |
LOAD |
TAX |
LOAD |
TAX |
MPY |
=0,98 |
STORE |
$1 |
ADD |
PRICE |
STORE |
COST |
LOAD |
$1 |
MPY |
$2 |
|
|
ADD |
PRICE |
STORE |
COST |
|
|
MPY |
$2 |
|
|
|
|
STORE |
COST |
|
|
|
|
|
|
|
|||
Применяем правило 1) |
Удаляем последова- |
К последовательно- |
|||
к последовательности |
тельность |
сти |
|
||
LOAD |
PRICE; |
STORE |
$1; |
LOAD |
=0.98; |
ФВВ |
;1 |
LOAD |
$1 |
STORE |
$2 |
Заменяем на |
|
|
Применяем правило |
||
LOAD |
$1 |
|
|
4) и удаляем их. |
|
ADD |
PRICE |
|
|
В команде |
|
|
|
|
|
MPY |
$2 |
|
|
|
|
Заменяется $2 на |
|
|
|
|
|
MPY |
=0,98 |
2.9. Исправление ошибок
Предположим, что входом компилятора служит правильно построенная программа (однако, на практике очень часто это не так).
Компилятор имеет возможность обнаружить ошибки в программе по крайней мере на трех этапах компиляции:
-лексического анализа;
-синтаксического анализа;
-генерации кода.
Если встретилась ошибка, то компилятору трудно по неправильной программе решить, что имел в виду ее автор. Но в некоторых случаях легко сделать предположение о возможном исправлении программы.
Например, если А=В*2С, то вполне правдоподобно допустить А=В*2*С. В общем случае компилятор зафиксирует эту ошибку и остановится. Однако некоторые компиляторы стараются провести минимальные изменения во входной цепочке, чтобы продолжить работу.
Перечислим несколько возможных изменений.
·Замена одного знака. Если лексический анализатор выдает синтаксическое слово INTEJER в неподходящем для появления иденти-

40
фикатора месте программы, то компилятор может догадаться, что подразумевается слово INTEGER.
·Вставка одной лексемы, т.е. заменить 2С на 2*С.
·Устранение одной лексемы. DO 10 I=1,20,.
·Простая перестановка лексем. I INTEGER на INTEGER I.
Далее мы подробно остановимся на реализации таких компиляторов.
2.10.Резюме
На рис. 2.5. приведена принципиальная модель компилятора, которая является лишь первым приближением к реальному компилятору. В реальности фаз может быть значительно больше, т.к. компиляторы должны занимать как можно меньший объем памяти.
|
|
|
|
|
|
|
Работа с таблицей |
|
|
|
|
|
|||
Исходная |
|
|
|
|
|
|
|
|
|
|
|
|
|
||
|
|
|
|
|
|
|
|
|
|
|
|
|
|||
программа |
|
|
|
|
|
|
|
|
|
|
|
|
|
||
Лексический |
|
|
Синтаксический |
|
|
Генерация |
|
Оптимизация |
|
ассембли |
|||||
|
|
|
|
|
|
|
|
|
|||||||
|
|
|
анализатор |
|
|
анализатор |
|
|
кода |
|
кода |
|
рование |
||
|
|
|
|
|
|
|
|
|
|||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Анализ ошибок
Рис 2.8. Модель компилятора
Мы будем интересоваться фундаментальными проблемами, возникающими при построении компиляторов и других устройств, предназначенных для обработки языков.
Контрольные вопросы
1.Задание языков программирования.
2.Синтаксис и семантика.
3.Процесс компиляции.
4.Лексический анализ.
5.Работа с таблицами.
6.Синтаксический анализ.
7.Генерация кода.
8.Алгоритм генерации кода.