Опубликован: 08.04.2009 | Доступ: свободный | Студентов: 485 / 0 | Длительность: 17:26:00
Специальности: Программист
Лекция 16:

Синтаксический разбор слева направо (LR)

< Лекция 15 || Лекция 16: 1234

16.3. SLR(1)-грамматики

Напомним, что для любого нетерминала K мы определяли (см. "пункт 15.3." ) множество {Послед}({K}) тех терминалов, которые могут стоять непосредственно за {K} в выводимом (из начального нетерминала) слове; в это множество добавляют также символ EOI, если нетерминал K может стоять в конце выводимого слова.

16.3.1. Доказать, что если в данный момент LR-процесса последний символ стека S равен K, причем процесс этот может в дальнейшем успешно завершиться, то Next принадлежит {Послед}({K}).

Решение. Этот факт является непосредственным следствием определения (вспомним соответствие между правыми выводами и LR-процессами).

Рассмотрим некоторую грамматику, произвольное слово S из терминалов и нетерминалов и терминал x. Если множество {Сост}({S}) содержит ситуацию, в которой справа от подчеркивания стоит терминал x, то говорят, что для пары \langle{S},{x}\rangle возможен сдвиг. Если в {Сост}({S}) есть ситуация {K}\to{U}\_\,, причем x принадлежит {Послед}({K}), то говорят, что для пары \langle{S},{x}\rangle SLR(1)-возможна свертка (по правилу {K}\to{U} ). Говорят, что для пары \langle{S},{x}\rangle возникает SLR(1)-конфликт типа сдвиг/свертка, если возможны и сдвиг, и свертка. Говорят, что для пары \langle{S},{x}\rangle возникает SLR(1)-конфликт типа свертка/свертка, если есть несколько правил, по которым возможна свертка.

Грамматика называется SLR(1)-грамматикой, если в ней нет SLR(1)-конфликтов типа сдвиг/свертка и свертка/свертка ни для одной пары \langle{S},{x}\rangle.

16.3.2. Пусть дана SLR(1)-грамматика. Доказать, что у любого слова существует не более одного правого вывода. Построить алгоритм проверки выводимости в SLR(1)-грамматике.

Решение. Аналогично случаю LR(0)-грамматик, только при выборе между сдвигом и сверткой учитывается очередной символ ( Next ).

16.3.3. Проверить, является ли приведенная выше в "задаче 16.1.10." грамматика (с нетерминалами E, T и F ) SLR(1)-грамматикой.

Решение. Да, является, так как оба конфликта, мешающие ей быть LR(0)-грамматикой, разрешаются с учетом очередного символа: и для слова T, и для слова E+T сдвиг возможен только при {Next}={*}, а символ * не принадлежит ни {Послед}({E}) = \{{EOI},{+},{)}\}, ни {Послед}({T}) = \{{EOI},{+},{*},{)}\}, и поэтому при {Next}={*} свертка невозможна.

16.4. LR(1)-грамматики, LALR(1)-грамматики

Описанный выше SLR(1)-подход используют не всю возможную информацию при выяснении того, возможна ли свертка. Именно, он отдельно проверяет, возможна ли свертка при данном состоянии стека S и отдельно - возможна ли свертка по данному правилу при данном символе Next. Между тем эти проверки не являются независимыми: обе могут дать положительный ответ, но тем не менее свертка при стеке S и очередном символе Next невозможна. В LR(1)-подходе этот недостаток устраняется.

LR(1)-подход состоит вот в чем: все наши определения и утверждения модифицируются так, чтобы учесть, какой символ стоит справа от разворачиваемого нетерминала (другими словами, чему равен Next при свертке).

Пусть {K}\to{U} - одно из правил грамматики, а t - некоторый терминал или спецсимвол EOI (который мы домысливаем в конце входного слова). Определим множество {ЛевКонт}({K}\to{U},{t}) как множество всех слов, которые являются содержимым стека непосредственно перед сверткой U в K в ходе успешного LR-процесса, при условии {Next} = {t} (в момент свертки).

Если отбросить у всех слов из {ЛевКонт}({K}\to{U}) их конец U, то получится множество всех слов, которые могут появиться в правых выводах перед нетерминалом K, за которым стоит символ t. Это множество (не зависящее от того, какое из правил {K}\to{U} для нетерминала K выбрано) мы будем обозначать {Лев}({K},{t}).

16.4.1. Написать грамматику для порождения множеств {Лев}({K},{t}).

Решение. Ее нетерминалами будут символы \langle{ЛевK}\:{t}\rangle для каждого нетерминала K и для каждого терминала t (а также для {t}={EOI} ). Ее правила таковы. Пусть P - начальный нетерминал исходной грамматики. Тогда в новой грамматике будет правило

\langle {ЛевP}\:{EOI}\rangle\to \qquad
    \hbox{(пустое слово).}
Каждое правило исходной грамматики порождает несколько правил новой. Например, для правила
{K}\to{L}\,{u}\,{M}\,{N}
( L, M, N - нетерминалы, u - терминал) в новую грамматику мы добавим правила
\langle{ЛевL}\:{u}\rangle \to
   \langle{ЛевK}\:{x}\rangle
(для всех терминалов x );
\langle{ЛевM}\:{s}\rangle \to
   \langle{ЛевK}\:{y}\rangle\,{L}\,{u}
(для всех s, которые могут начинать слова, выводимые из N, и для всех y, а также для всех пар {s} =
{y}, если из N выводимо пустое слово);
\langle{ЛевN}\:{s}\rangle \to
   \langle{ЛевK}\:{s}\rangle\,{L}\,{u}\,{M}
(для всех терминалов s ).

16.4.2. Как меняется определение ситуации?

Решение. Ситуацией называется пара

[
\text{ситуация в старом смысле},
\text{терминал или {EOI}}
]

< Лекция 15 || Лекция 16: 1234