
- •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. Расширенный вывод для АТ-грамматики

2. Контекстно-свободные грамматики и автоматы
2.1. Приведенные грамматики
Из четырех типов грамматик контекстно-свободные грамматики являются наиболее важными с точки зрения приложений к языкам программирования и компиляции. Рассмотрим несколько эквивалентных преобразований КС-грамматик. Первый вид преобразования связан с удалением из грамматики бесполезных символов. Бесполезные символы в грамматике могут оказаться в следующих случаях:
а) из символа не может быть получена конечная терминальная цепочка, б) символ не может быть получен при выводе.
2.2. Удаление непроизводящих символов
Определение. Символ <X> VA называется непроизводящим, если из него не может быть выведена конечная терминальная цепочка.
Если все символы правой части являются производящими, то производящим является и символ, стоящий в левой части. Это утверждение позволяет описать алгоритм обнаружения непроизводящих символов:
1.Составить список нетерминалов, для которых найдется хотя бы одно правило, правая часть которого не содержит нетерминалов.
2.Если найдено такое правило, что все нетерминалы, стоящие в его правой части уже
занесены в список, то добавить в список нетерминал, стоящий в его левой части. 3. Если на шаге 2 список больше не пополняется, то получен список всех произво-
дящих нетерминалов грамматики, а все нетерминалы, не попавшие в него, являются не-
14
производящими.
Проанализируем следующую грамматику :
Г2. 0: R = {<I>→a<I>a, <I>→b<A>d, <I>→c, <A>→c<B>d, <A>→a<A>d, <B>→d<A>f },
Здесь непроизводящими являются символы <А> и <В>. После удаления правил, содер-
жащих непроизводящие символы, получаем: R' = {<I> →a<I>a, <I>→ c}.
2.3. Определение недостижимых символов
Определение. Символ X VT VA называется недостижимым в КС-грамматике Г, если X не появляется ни в одной выводимой цепочке.
Можно заметить, что если нетерминал в левой части правила является достижимым, то и все символы правой части являются достижимыми. Это свойство правил является основой процедуры выявления недостижимых символов, которую можно записать так:
1.Образовать одноэлементный список, состоящий из начального символа
2.Если найдено правило, левая часть которого уже имеется в списке, то включить в список все символы, содержащиеся в его правой части.
3.Если на шаге 2 новые нетерминалы в список больше не добавляются, то получен список всех достижимых нетерминалов, а нетерминалы, не попавшие в список, являются недостижимыми.
Рассмотрим грамматику:
Г2. 1 : R = { <I> →a<I>b, <I> →c, <A> →b<I>,
15
<A> →a }
Находим, что A является недостижимым символом.
2.4. Определение бесполезных символов
Бесполезный символ грамматики можно определить следующим образом:
Определение. Символ X, который принадлежит VT VA называется бесполезным в КС-грамматике Г, если он является недостижимым или непроизводящим.
Исключить бесполезные символы из грамматики можно удаляя правила, содержащие вначале непроизводящие, а затем недостижимые символы.
Определение. КС-грамматика называется приведенной, если она не содержит бесполезных символов.
2.5. Исключение леворекурсивных правил
Определение. Правило вида <A> → α <A> , где A VA , α ( VT VA) * , называется
праворекурсивным, а правило вида <A> → <A>α - леворекурсивным.
Для каждой КС-грамматики Г, содержащей леворекурсивные правила, можно построить эквивалентную грамматику Г', не содержащую леворекурсивных правил.
Пусть исходная грамматика Г содержит правила:
<A> → <A>α 1 | <A>α 2 | ... |<A>α m| β 1 | β 2 |...| β n ,
где ни одна цепочка β не начинается с <A> и αi, βj ( VT VA)* i =- 1,…,m . j = 1,…,n Введем новый нетерминал <A'> и преобразуем правила следующим образом:
<A> → β 1 | β 2 |...| β n | β 1<A'> | β 2<A'>|...| β n<A'>, <A'> →α 1 | α 2 |...| α m| α 1<A'> |α 2<A'>|...|α m<A'>.
Заменяя все правила с левой рекурсией в Г описанным способом, получим грамматику Г', такую что L(Г)=L(Г'), поскольку каждая цепочка, выведенная в грамматике Г, может быть построена в грамматике Г' и наоборот. Рассмотрим построение выводов в Г и Г'.
16
В грамматике Г вывод цепочки имеет вид:
< A> <A>α1 <A>α1α1 <A>α1α1α1 β1α1α1α 1,
в грамматике Г' эта же цепочка выводится следующим образом:
<A> β 1<A'> β1α 1<A'> β1α1α 1<A'> β1α1α1α 1.
Рассмотрим пример. Требуется преобразовать грамматику Г1. 9, которая задана схемой:
Г1. 9: R={<E> → <E> + <T> | <T>, < T> → <T> * <F> | <F>, <F> → ( <E> ) | a}.
Следуя описанному способу, правила <E> → <E> + <T> | <T> преобразуем в правила
<E>→ <T> | <T><E'> и <E'> → +<T> | +<T><E'> , а правила <T> → <T> * <F> | <F>
преобразуем в правила <T> → <F> | <F><T'> и <T'> → < F> | * <F><T'>.
В результате получаем грамматику Г'1. 9, имеющую схему:
Г'1. 9 : R'= { <E> → < T>, <E> → <T><E'>, <E'>→ + <T>,
<E'> → + <T><E'>, <T> → <F>,
<T> → <F><T'>, <T'> → * <F>, <T'> → * <F><T'>, < F> → a,
<F> → (<E>) },
не содержащую леворекурсивных правил.
2.6. Исключение цепных правил
Определение. Правило грамматики вида <A> → <B>, где <A>,<B> VA, называется
цепным.
Для КС-грамматики Г, содержащей цепные правила, можно построить эквивалентную ей грамматику Г', не содержащую цепных правил.
17