80
достичь конфигурации, в которой синтаксический анализатор по
информации о содержимом стека и об очередном входном символе не в
состоянии решить, должен ли использоваться перенос или свертка
(конфликт перенос/свертка
, shift/reduce conflict), либо какая из нескольких
возможных сверток должна применяться (конфликт свертка/свертка
,
reduce/reduce conflict). Сейчас мы рассмотрим несколько примеров
синтаксических конструкций, приводящих к построению таких грамматик.
Технически эти грамматики не входят в класс LR(k)-грамматик, мы говорим
о них как о не-LR-грамматиках. k в LR(k) означает количество символов
входного потока, следующих за текущим, которые синтаксический
анализатор может при необходимости просмотреть, не перенося в
стек.
Практически используемые грамматики в основном принадлежат классу
LR(1).
Пример 13.d
Неоднозначная грамматика не может быть LR-грамматикой.
Рассмотрим классический случай грамматики "кочующего else":
stmt → if expr then stmt
| if expr then stmt else stmt
| other
Если ПС-анализатор находится в конфигурации
Стек Вход
$... if expr then stmt else ... $
то мы не можем сказать, является ли подстрока if expr then stmt
основой, независимо от того, что
находится в стеке под нею. Здесь возникает
конфликт перенос/свертка – в зависимости от того, что следует за else во
входном потоке, верным решением может оказаться свертка if expr then stmt
в stmt, а может – перенос else и поиск еще одного stmt для завершения
альтернативы if expr then stmt else stmt.
Таким образом, мы не можем сказать,
что следует использовать в данном случае – перенос или свертку, а значит,
грамматика не является LR(1)-грамматикой. Более того, никакая