- •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. Расширенный вывод для АТ-грамматики
и <B> является аннулирующим нетерминалом, т.е. существует <B> ==> *$, то функция
ПЕРВ(<B>µ')=ПЕРВ(µ') ПЕРВ(α 1) ПЕРВ(α 2) ... ПЕРВ(α n).
3.4.3. Построение функции СЛЕД(<B>)
Аргументом функции СЛЕД является нетерминальный символ а значение функции представляет собой множество терминалов, которые могут следовать непосредственно за этим нетерминалом в цепочках, выводимых из начального символа грамматики. Вычисление значения функции СЛЕД(<B>) должно выполняться по следующим правилам:
1) Если в схеме грамматики имеются правила вида
<X1> → µ1<B>α1, <X2> → µ2<B>α2, ... , <Xn> → µn<B>αn,
и все цепочки αi ≠ $, то
СЛЕД(<B>) = ПЕРВ(α1) ПЕРВ(α2) ... ПЕРВ(αn).
2) Если же среди приведенных выше правил имеется хотя бы одна цепочка αi = $,
например α1 = $, то функция вычисляется следующим образом:
СЛЕД(<B>) = СЛЕД(<X1>) ПЕРВ(α 2) ... ПЕРВ(α n).
3.4.4. Построение множества ВЫБОР
Множество ВЫБОР, которое используется для выбора переходов магазинных автоматов, определяется с помощью функций ПЕРВ и СЛЕД по правилам:
1)Если правило грамматики имеет вид <B> → α и α не является аннулирующей цепочкой, т.е. не существует вывод α *$, то
ВЫБОР(<B> → α ) = ПЕРВ( α ).
2)Для аннулирующих правил грамматики вида <B> →$, множество выбора определяется следующим образом
ВЫБОР(<B> → $) = СЛЕД(<B>).
3)Если правило грамматики имеет вид <B> → µ и µ является аннулирующей цепочкой, то
ВЫБОР(<B> → µ) = ПЕРВ(µ) СЛЕД(<B>).
3.5.Слаборазделенные грамматики
Определение. КС-грамматика называется слаборазделенной, если выполняются следую-
32
щие три условия:
1)правая часть каждого правила представляет собой либо пустую цепочку $, либо начинается с терминального символа,
2)если два правила имеют одинаковые левые части, то правые части правил должны начинаться разными символами,
3)для каждого нетерминала <A>, такого что <A> ==>* $ множество начальных символов не должно пересекаться с множеством символов, следующих за A:
ПЕРВ(A) ∩ СЛЕД(A) = $
Используя приведенное определение, выясним, является ли следующая грамматика слаборазделенной:
Г3. 3 : R = {(1) <I> → a<A> ,
(2)<I> → b ,
(3)<A> → c<I>a ,
(4)<A> → $ }.
Эта грамматика не содержит правил с одинаковой левой частью, начинающихся одинаковыми терминалами, поэтому нужно проверить только условие (3) для правила (4). Вычисляя функции
ПЕРВ(<A>) = { c } и СЛЕД(<A>) = СЛЕД(<I>) = { a },
находим, что множество значений функции ПЕРВ(<A>) и множество значений функции СЛЕД(<A>) не имеют общих элементов. Следовательно, грамматика Г3.3 является слаборазделенной.
3.6. LL(1) - грамматики
Разделенные и слаборазделенные грамматики представляют собой подклассы грамматик, которые называются LL(1) грамматиками, и которые определяются следующим образом. Определение. КС-грамматика является LL(1) грамматикой тогда и только тогда, когда выполняются условия:
1. Для каждого нетерминала, являющегося левой частью нескольких правил:
<A> →α1 | α2 | ... | αn,
необходимо, чтобы пересечение функций ПЕРВ(αi) и ПЕРВ(αj) было пусто для всех i ≠ j.
33
2. Для каждого аннулирующего нетерминала <A>, т.е. <A> * $,
необходимо, чтобы пересечение множеств ПЕРВ(<A>) и СЛЕД(<A>) было пустым. Грамматики LL(1), в отличие от разделенных и слаборазделенных грамматик, могут содержать правила, начинающиеся нетерминальными символами.
Данный класс грамматик можно определить также с помощью множеств выбора. Имеет место утверждение
КС-грамматика является LL(1) грамматикой тогда и только тогда, когда множества ВЫБОР, построенные для правил с одинаковой левой частью, не содержат одинаковых элементов.
3.7. Построение магазинного автомата
Для каждой LL(1) грамматики Г можно построить детерминированный магазинный автомат М, допускающий язык, порождаемый заданной грамматикой: L( Г ) = L( М ). Пусть задана грамматика Г = { VT, VA, I, R}. Требуется определить автомат
М = { P, S, s0, F, H, h0, f }.
Поскольку автомат должен допускать цепочки языка, порождаемого заданной грамматикой, положим P = VT. Для простоты, допустим, что автомат имеет одно состояние s0, которое является и начальным и заключительным, то есть - S = {s0} и F = {s0}.
В качестве магазинного алфавита выберем: H = { VT VA { h0 } }.
Построение функции переходов выполним с использованием множеств ВЫБОР для правил заданной грамматики следующим образом:
1) Для каждого правила грамматики, начинающегося терминальным символом вида
<A> → b α, построим команду автомата f( s0, b, <A> ) = ( s0, α' ),
где α' зеркальное отображение цепочки α.
2) Для каждого правила грамматики, начинающегося нетерминальным символом вида
<A> → <B> α, построим команду автомата f*( s0, x, <A> ) = ( s0, α'<B> )
где f* - команда автомата без сдвига входной головки, α' зеркальное отображение цепоч-
ки α, а x ВЫБОР(<A> → <B>α)
Количество команд для заданного правила, равно числу элементов множества ВЫБОР.
34
Команды магазинного автомата, работающие без сдвига входной головки, выполняют замену нетерминаала из левой части правила, цепочкой из правой части этого правила. Сопоставление терминального символа, получаемого при выводе, и очередного символа входной цепочки не производится, поэтому для таких команд сдвиг входной головки не происходит.
3) Для каждого аннулирующего правила грамматики вида <A> → $ построим команды автомата
f*( s0, x, <A> ) = ( s0, $ )
для каждого элемента x из множества ВЫБОР(<A> → $). Количество таких команд равно числу элементов множества ВЫБОР.
4) Для каждого терминального символа b, расположенного в середине или на конце правых частей правил грамматики, построим команду
f( s0, b, b ) = ( s0, $ ).
5) Для перехода в заключительное состояние используем команду f*( s0, ε, h0 ) = ( s0, $, $ ).
В качестве начальной конфигурации автомата с заданной входной цепочкой µ выберем:
(s0, µ, h0<I>).
Построим магазинный автомат для грамматики Г3. 5, схема которой имеет вид
Г3. 5 : R = {<A> → x | (<B>), <B> → <A> <C>,
<C> → + <A> <C> | $ }.
Построим множества ВЫБОР для каждого из правил и проверим, является ли эта грамматика LL(1) грамматикой.
(1)ВЫБОР(<A> → x) = ПЕРВ(x) = { x }
(2)ВЫБОР(<A> → (<B>)) = ПЕРВ((<B>)) = { ( }
(3)ВЫБОР(<B> → <A><C>) = ПЕРВ(<A><C>) = ПЕРВ(<A>) = { x, ( }
(4)ВЫБОР(<C> → +<A><C>) = ПЕРВ(+<A><C>) = { + }
(5)ВЫБОР(<C> → $) = СЛЕД(<C>) = СЛЕД(<B>) = { ) }.
Множества выбора для правил с символом <A> в левой части и для правил с символом <C> в левой части не имеют общих элементов, следовательно, рассматриваемая грамматика относится к классу LL(1) грамматик.
35