
- •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. Расширенный вывод для АТ-грамматики
Например, рассмотренный вывод цепочки i * i + i в грамматике Г1. 9 является левосторонним выводом.
1.3.8. Неоднозначные и эквивалентные грамматики
Существуют грамматики, в которых одна и та же цепочка может быть получена с помощью различных выводов.
Данное свойство грамматик называется неоднозначностью.
Определение. Цепочка языка L(Г) называется неоднозначной, если для её вывода существует более чем одно синтаксическое дерево. Если грамматика Г порождает неоднозначную цепочку, то она называется неоднозначной.
Можно сделать следующие выводы:
1)каждой цепочке, выводимой в грамматике, может соответствовать одно или несколько синтаксических деревьев,
2)каждому синтаксическому дереву могут соответствовать несколько выводов,
3)каждому синтаксическому дереву соответствует единственный правый и единственный левый выводы.
Один и тот же язык может быть получен с помощью различных грамматик.
Определение. Две грамматики Г1 и Г2 называются эквивалентными, ecли они порождают один и тот же язык, т.е.
L(Г1) = L(Г2).
1.4. Способы задания схем грамматик
Схема грамматики содержит правила вывода, определяющие синтаксис языка. Для задания правил используются различные формы описания: символическая (рассмотренная ранее), форма Наура-Бэкуса, итерационная форма и синтаксические диаграммы.
1.4.1. Форма Наура-Бэкуса
При описании синтаксиса конкретных языков программирования приходится вводить большое число нетерминальных символов, и символическая форма записи теряет свою наглядность. В этом случае применяют форму Наура-Бэкуса (ФНБ), которая предполагает использование в качестве нетерминальных символов комбинаций слов естественно-
10
го языка, заключенных в угловые скобки, а в качестве разделителя - специального знака, состоящего из двух двоеточий и равенства
Чтобы сократить описание схемы грамматики, в ФНБ разрешается объединять правила c одинаковой левой частью в одно правило, правая часть которого должна включать правые части объединяемых правил, разделенные вертикальной чертой. Например:
<список>::=<элемент списка><список>|<элемент списка>.
1.4.2. Итерационная форма
Для получения более компактных описаний синтаксиса применяют итерационную форму описания. Такая форма предполагает введение специальной операции, которая называется итерацией и обозначается парой фигурных скобок со звездочкой. Итерация вида {a}* определяется как множество, включающее цепочки всевозможной длины, построенные с использованием символа a, и пустую цепочку.
{a}* = {$, a, aa, aaa, aaaa,...}.
Используя итерацию для описания множества цепочек, задаваемых символическими правилами, для списка получаем:
<L> → <E> {<E>}*.
Например, описание множества цепочек, каждая из которых должна начинаться знаком # и может состоять из произвольного числа букв x и y, может быть представлено в итерационной форме так:
<I> → #{x | y}* .
В итерационных формах описания наряду с итерационными скобками часто применяют квадратные скобки для указания того, что цепочка , заключенная в них, может быть опущена. С помощью таких скобок правила:
<A> → x<A>y<B>z и <A> → x<B>z
могут быть представлены в виде:
<A> → x[<A>y]<B>z.
1.4.3. Синтаксические диаграммы
Для того, чтобы улучшить зрительное восприятие и облегчить понимание сложных синтаксических описаний, применяют представление правил грамматики в виде синтаксических диаграмм. Правила построения таких диаграмм можно сформулировать в следующем виде:
11

1)Каждому правилу вида <A> → α1 | α2 |...| αk ставится в соответствие диаграмма, структура которой определяется правой частью правила.
2)Каждое появление терминального символа x в цепочке αi изображается на диаграмме дугой, помеченной этим символом x, заключенным в кружок.
3)Каждому появлению нетерминального символа <A> в цепочке αi ставится в соответствие на диаграмме дуга, помеченная символом, заключённым в прямоугольник.
4)Порождающее правило, имеющее вид:
<A> → a1a2...an
изображается на диаграмме следующим образом:
5) Порождающее правило, имеющее вид:
<A> → a1 | a2 | ... | an
изображается на диаграмме так:
6) Если порождающее правило задано в виде итерации:
<A> → {a}*,
12

то ему соответствует диаграмма:
Число синтаксических диаграмм, которые можно построить для заданной схемы грамматики, определяется числом правил. Чтобы сократить число диаграмм, их объединяют, заменяя нетерминальные символы, входящие в диаграмму, построенными для них диаграммами.
Правила 3-6 предусматривают, что в качестве цепочек ai на объединенной диаграмме могут быть использованы диаграммы, построенные для этих цепочек. В качестве примера рассмотрим следующую грамматику с начальным символом <A> :
Г1. 14: VT = { x, +, (, ) }, VA = {<A>, <B>, <C>}, R = {<A> → x | (<B>),
<B> → <A><C>, <C> → {+<A>}*}.
Синтаксические диаграммы для такой грамматики имеют вид:
Заменяя нетерминальные символы, соответствующими диаграммами, получаем объединенную диаграмму в виде:
13