- •1.1. Основные понятия
- •1.1.1. Трансляторы, интерпретаторы и компиляторы
- •1.1.2. Стадии работы компилятора
- •1.1.3. Построение компилятора
- •1.2. Определение формальной грамматики и языка
- •1.2.1. Первичные понятия
- •1.3.3. Грамматики типа 2
- •1.3.4. Грамматики типа 3
- •1.3.5. Вывод в КС-грамматиках и правила построения дерева вывода
- •1.3.6. Синтаксический разбор
- •1.3.7. Левый и правый выводы
- •1.3.8. Неоднозначные и эквивалентные грамматики
- •1.4. Способы задания схем грамматик
- •1.4.1. Форма Наура-Бэкуса
- •1.4.2. Итерационная форма
- •1.4.3. Синтаксические диаграммы
- •2. Контекстно-свободные грамматики и автоматы
- •2.1. Приведенные грамматики
- •2.2. Удаление непроизводящих символов
- •2.3. Определение недостижимых символов
- •2.4. Определение бесполезных символов
- •2.5. Исключение леворекурсивных правил
- •2.6. Исключение цепных правил
- •2.7. Преобразование неукорачивающих грамматик
- •2.8. Магазинные автоматы
- •2.9. Работа магазинного автомата
- •2.10. Язык, допускаемый магазинным автоматом
- •2.11. Построение магазинного автомата
- •2.12. Пример построения автомата
- •3. Нисходящие распознаватели
- •3.1. Распознаватели и LL(K) - грамматики
- •3.2. Разделенные грамматики
- •3.3. Построение детерминированного нисходящего распознавателя
- •3.4. Множество выбора
- •3.4.1. Функции ПЕРВ, СЛЕД и множество ВЫБОР
- •3.4.2. Построение функции ПЕРВ(µ)
- •3.4.3. Построение функции СЛЕД(<B>)
- •3.4.4. Построение множества ВЫБОР
- •3.5. Слаборазделенные грамматики
- •3.6. LL(1) - грамматики
- •3.7. Построение магазинного автомата
- •3.8. Преобразование грамматик к виду LL(1)
- •3.8.1. Исключение леворекурсивных правил
- •3.8.2. Выделение общих частей
- •3.9. Восходящие распознаватели
- •4. Методы трансляции
- •4.1. Основные понятия
- •4.2. Синтаксически управляемые схемы
- •4.3. Перевод, определяемый СУ - схемой
- •4.4. Простая СУ – схема
- •4.5. Построение простой СУ - схемы
- •4.6. Транслирующие грамматики
- •4.7. Входная и выходная грамматики заданной транслирующей граммагики
- •4.8. Построение транслирующей грамматики по СУ - схеме
- •4.8.1. Бесскобочные выражения
- •4.8.1.1. Префиксная польская запись (ПрПЗ)
- •4.8.1.2. Вычисление префиксных польских записей
- •4.8.1.3. Постфиксная польская запись
- •4.8.1.4. Вычисление постфиксных записей
- •4.9. Магазинные преобразователи
- •4.9.1. Определение магазинного преобразователя
- •4.9.2. Описание работы магазинного преобразователя
- •4.9.5. Пример построения преобразователя
- •4.9.6. Порядок построения детерминированного магазинного преобразователя
- •5.1. Определение AT-грамматик
- •5.2. Пример АТ-грамматики
- •5.3. Вычисление значений атрибутов с левым выводом
- •5.4. L - атрибутные транслирующие грамматики
- •5.4.1. Форма простого присваивания АТ-грамматик
- •5.4.2. Преобразование LАТ-грамматики в LАТ-грамматику в форме простого присваивания
- •5.4.3. Расширенный вывод для АТ-грамматики
ω ( VT VA)*. Цепочки χ1 и χ2 остаются неизменными при применении правила, поэтому их называют контекстом (соответственно левым и правым), а грамматику – кон- текстно-зависимой.
1.3.3. Грамматики типа 2
Грамматики типа 2 называют контектно-свободными или бесконтекстными грамматиками ( КС-грамматики или Б-грамматики).
Правила вывода таких грамматик имеют вид:
<A> → α,
где <A> VA и α ( VT VA)*.
Эти правила получаются из правил грамматики типа 1 при условии χ1 = χ2 = $. Такие грамматики используются для описания языков программирования. Примером КСграмматики может служить следующая грамматика:
Г1. 5:
VT = {a, b}, VA = {<I>}, R = { <I> → a<I>a, <I> → b<I>b,
<I> → aa, <I> → bb}.
Эта грамматика порождает язык, который состоит из цепочек, каждая из которых в свою очередь состоит из двух частей, цепочки β VT* и зеркального отображения этой це-
почки β'.
L( Г1.5 ) = { ββ' | β VT+},
где VT+ - это множество VT* без пустой цепочки. С помощью правил этой грамматики может быть построена, например, следующая цепочка:
<I> a<I>a ab<I>ba aba<I>aba ababbaba.
1.3.4. Грамматики типа 3
Грамматики типа 3 называют автоматными грамматиками (А - грамматиками).
Правила вывода в таких грамматиках имеют вид:
<A> → a или <A> → a<B> или <A> → <B>a,
6
где a VT, <A>, <B> VA, причем грамматика может иметь только правила вида
<A> → a<B> - правосторонние правила, либо только вида <A> → <B>a - левосторонние правила. Примерами автоматных грамматик могут служить правосторонняя грамматика Г1. 6 и левосторонняя грамматика Г1. 7.
Г1. 6:
VT = {a, b}, VA = {<I>, <A>, <Z>}, R = { <I> → a<I>,
<I> → a<A>, <A> → b<A>, <A> → b<Z>, <Z> → $ }.
Г1. 7:
VT = {a, b}, VA = {<I>, <A>>, <Z>}, R = { <I> → <A>b,
<A> → <A>b, <A> → <Z>a, <Z> → <Z>a, <Z> → $ }.
Эти грамматики являются эквивалентными и порождают язык
L(Г7) = {anbm | n,m > 0}.
Между множествами языков различных типов существует отношение включения:
{ L типа 3 } { L типа 2} { L типа 1} {L типа 0}.
Доказано, что существуют языки типа 0, не являющиеся языками типа 1, языки типа 2, не являющиеся языками типа 1, и языки типа 3, не являющиеся языками типа 2.
Наибольшее практическое применение находят грамматики типа 2 и типа 3. В дальнейшем будем рассматривать именно эти типы грамматик.
7
1.3.5. Вывод в КС-грамматиках и правила построения дерева вывода
Формальные грамматики позволяют задавать языки, представляющие множества цепочек, построенных по определенным правилам. Используемый способ задания позволяет построить любую цепочку, принадлежащую языку. Чтобы сделать процесс построения, называемый выводом, наглядным, его изображают в виде графа, точнее, в виде дерева, которое называют синтаксическим деревом или деревом вывода. Учитывая, что вывод любой цепочки языка, принадлежащей языку, порождаемому заданной грамматикой, должен начинаться с начального символа, правила построения дерева можно сформулировать следующим образом:
1)В качестве начальной вершины или корня дерева выбирается вершина, обозначаемая начальным символом грамматики <I>; эта вершина образует нулевой ярус дерева,
2)Если при выводе цепочки на очередном шаге используется правило грамматики
<A> → α и вершина, помеченная нетерминалом <A>, расположена на ярусе с номером k- 1, то к построенному дереву добавляется столько вершин, сколько содержится символов в цепочке α. Эти вершины располагаются на ярусе k , обозначяются символами цепочки
α и соединияются дугами с вершиной <A>. Результатом вывода является множество конечных узлов - листьев, которые выписываются при обходе дерева слева - вниз - направо - вверх . Рассмотрим, например, грамматику Г1. 8:
Г1. 8:
VT = {a, b}, VA = {<I>}, R = {<I> → a<I>b,
<I> → ab },
которая порождает язык L(Г8) = { anbn }, где а и b повторяются по n раз, n=1,2,...
Вывод цепочки a3b3 с помощью правил этой грамматики имеет вид:
8