
- •Теория вычислительных процессов и структур
- •1. Предварительные математические сведения
- •1.2. Операции над множествами Объединение множеств
- •Пересечение множеств
- •Разность множеств
- •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.9. Исправление ошибок
- •2.10. Резюме
- •3. Теория языков
- •3.1. Способы определения языков
- •3.2. Грамматики
- •Пример.
- •3.3. Грамматики с ограничениями на правила
- •3.4. Распознаватели
- •3.5. Регулярные множества, их распознавание
- •3.6. Регулярные множества и конечные автоматы
- •3.7. Графическое представление конечных автоматов
- •3.8. Конечные автоматы и регулярные множества
- •3.9. Минимизация конечных автоматов
- •3.10. Контекстно-свободные языки
- •3.10.1. Деревья выводов
- •3.10.2. Преобразование кс–грамматик
- •3.10.3. Грамматика без циклов
- •3.10.4. Нормальная форма Хомского
- •3.10.5. Нормальная формула Грейбах
- •3.11. Автоматы с магазинной памятью
- •3.11.1. Основные определения
- •3.11.2. Эквивалентность мп-автоматов и кс-грамматик
- •4.1. Эквивалентность мп-автоматов и кс-грамматик
- •4.2. Ll(1)-грамматики
- •4.3. Ll(1)-таблица разбора
- •5. Синтаксический анализ снизу вверх
- •5.1. Разбор снизу вверх
- •5.2. Lr(1) - таблица разбора
- •5.3. Построение lr – таблицы разбора
- •5.4. Сравнение ll – и lr – методов разбора
- •6. Включение действий в синтаксис
- •6.1. Получение четверок
- •6.2. Работа с таблицей символов
- •7. Проектирование компиляторов
- •7.1. Число проходов
- •7.2. Таблицы символов
- •Identifier, type.
- •Int procedure rehash(int n)
- •Int procedure rehash(int n)
- •7.3. Таблица видов
- •8. Распределение памяти
- •8.1. Стек времени прогона
- •Integer a, b, X, y
- •Int table[1:10, -5:5].
- •8.2. Методы вызова параметров
- •8.3. Обстановка выполнения процедур
- •8.4. «Куча»
- •8.5. Счетчик ссылок
- •8.6. Сборка мусора
- •9. Генерация кода
- •(Тип – адреса, номер - блока, смещение).
- •9.2. Структура данных для генерации кода
- •9.3. Генерация кода для типичных конструкций
- •9.3.1. Присвоение
- •9.3.2. Условные зависимости
- •If b then c else d
- •9.3.3. Описание идентификаторов
- •9.3.4. Циклы
- •9.3.5. Вход и выход из блока
- •9.3.6. Прикладные реализации
- •9.4. Проблемы, связанные с типами
- •9.5. Время компиляции и время прогона
- •10. Исправление и диагностика ошибок
- •10.1. Типы ошибок
- •10.2. Лексические ошибки
- •10.3. Ошибки в употреблении скобок
- •Begin end
- •Case esac
- •10.4. Синтаксические ошибки
- •10.5. Методы исправления синтаксических ошибок
- •End begin
- •10.6. Предупреждения
- •10.7. Сообщения о синтаксических ошибках
- •10.8. Контекстно-зависимые ошибки
- •Identifier xyz not declared
- •Identifier blank alredy declared in block
- •10.9. Ошибки, связанные с употреблением типов
- •Int I; char c;
- •10.10. Ошибки, допускаемые во время прогона
- •10.11. Ошибки, связанные с нарушением ограничений
3.10. Контекстно-свободные языки
Из четырёх классов грамматики иерархии Хомского класс контекстно-свободных языков наиболее важен с точки зрения приложения к языкам программирования и компиляции. С их помощью можно определить большую часть синтаксических структур языков программирования. Кроме того, они служат основой различных схем перевода, т.к. в ходе процесса компиляции синтаксическую структуру, передаваемую входной программе КС-грамматикой, можно использовать при построении перевода этой программы.
Синтаксическую структуру входной цепочки можно определить по последовательности правил, применяемых при выводе этой цепочки. Таким образом, на часть компилятора, называемую синтаксическим анализатором, можно смотреть как на устройство, которое пытается выяснить, существует ли в некоторой фиксированной КС-грамматике вывод входной цепочки.
Естественно, что эта задача нетривиальная – по данной КС-грамматике G и входной цепочке w выяснить, принадлежит ли w языку L(G), и если «да», то найти вывод цепочки w в грамматике G.
3.10.1. Деревья выводов
В грамматике может быть несколько выводов, эквивалентных в том смысле, что во всех них применяются одни и те же правила в одних и тех же местах, но в различном порядке. КС-грамматика позволяет ввести удобное графическое представление класса эквивалентных выводов, называемое деревом выводов.
Определение.
Дерево вывода в КС-грамматике G = (N, Р S),
где N – конечное множество нетерминальных символов;
- непересекающееся с N множество терминальных символов;
Р – конечное подмножество множества (N)N(N) (N) (элемент ( ) множества Р называется правилом или продукцией );
S – выделенный символ из N, называемый начальным или исходным символом,
- это помеченное упорядоченное дерево, каждая вершина которого помечена символом из множества N{e}.
Если
внутренняя вершина помечена символом
А, а её прямые потомки - символами
,
то А
– правило грамматики.
Определение.
Помеченное упорядоченное дерево D называется деревом вывода (или деревом разбора) в КС-грамматике G(А) = (N, Р A), если выполняются следующие условия:
корень дерева помечен А;
если
– поддеревья, над которыми доминируют прямые потомки корня дерева, и корень
помечен
, то А
– правило из множества Р.
должно быть деревом вывода в грамматике G(
) = (N, Р
), если
– нетерминал, и
состоит из единственной вершины, помеченной
, если
- терминал.
Пример. Имеем грамматику G=G(S) с правилами SaSbS | bSaS | e (рис.3.7).
Рис.
3.7. Деревья выводов
SaSbS
| bSaS
| e
Заметим, что существует единственное упорядочение вершин упорядоченного дерева, у которого прямые потомки вершины упорядочиваются «слева направо».
Допустим,
что n
– вершина и
– её прямые потомки. Тогда если i<j,
то вершина
и все её потомки считаются расположенными
левее вершины
и всех её потомков.
Определение.
Кроной дерева вывода назовём цепочку, которая получится, если выписать слева направо метки листьев.
Кроны наших деревьев: S, е, abab, abab.
Определение.
Сечением дерева D назовём такое множество С вершин дерева D, что
никакие две вершины из С не лежат на одном пути в D;
ни одну вершину дерева D нельзя добавить к С, не нарушив свойства 1).
Пример.
Множество вершин дерева, состоящего из одного корня, является сечением.
Листья также образуют сечение.
Рис. 3.8. Пример сечения дерева
Определение.
Кроной сечения дерева D является цепочка, получаемая конкатенацией (в порядке слева направо) меток вершин, образующих некоторое сечение.
Крона сечения примера, приведенного на рис.3.7, - abaSbS.
Лемма.
Пусть
S=
– вывод цепочки
из S в КС – грамматике G
= (N, Р S). Тогда в G
можно построить дерево вывода D, для
которого
– крона, а
– некоторые из крон сечения.
Лемма.
Пусть D – дерево вывода в КС-грамматике G = (N, Р S) с кроной . Тогда S (транзитивное и рефлексивное замыкание , т.е. выводима из S).
Доказательство.
Пусть
– такая последовательность сечений
дерева D, что
С0 – содержит только один корень дерева D;
для 0i<n получается из
заменой одной нетерминальной вершины её прямыми потомками;
– крона дерева D.
Ясно, что хотя бы одна такая последовательность существует.
Если
– крона сечения
,
то существующий вывод
называется левым выводом цепочки
из 0
в грамматике G.
Правый вывод определяется аналогично.
Если
S=
= w
– левый вывод терминальной цепочки w,
то каждая цепочка
(0i<n)
имеет вид
,
где
,
N
и
(N).
Каждая
следующая цепочка
левого вывода получается из предыдущей
цепочки
заменой самого левого нетерминала
правой частью некоторого правила.
Пример. Рассмотрим КС-грамматику G0 с правилами
EE+T | T
TТ*F | F
F(Е) | a.
Нарисуем дерево вывода (рис 3.7).
Рис. 3.9. Пример дерева вывода
Это дерево служит представлением десяти эквивалентных выводов цепочки а+а.
Е Е+Т Т+Т F+Т а+Т а+Fа+а – левый вывод.
Е Е+Т Е+F Е+а Т+а F+аа+а – правый вывод.
Определение.
Цепочку будем называть левовыводимой,
если существует левый вывод S=
= , и писать S
.
Аналогично будем называть правовыводимой,
если существует правый вывод S=
= , и писать S
.
Один шаг левого вывода будем обозначать
,
а правого