Почему эта грамматика не имеет конфликта уменьшения / уменьшения?
Рассмотрим следующую (по общему мнению, бессмысленную - она была значительно упрощена для иллюстрации сути) грамматику:
negationExpression
: TOK_MINUS constantExpression %prec UNARYOP
| testRule
;
constantExpression
: TOK_INTEGER_CONSTANT
| TOK_FLOAT_CONSTANT
;
testRule
: negationExpression constantExpression // call this Rule 1
| constantExpression // Rule 2
;
Бизон не жалуется на конфликты уменьшения / уменьшения при использовании этой грамматики, но мне кажется, что она есть. Предположим, мы проанализировали negationExpression
и constantExpression
; мне кажется, есть две вещи, которые парсер теперь может сделать, основываясь на приведенном выше определении:
- Уменьшите последовательность в
testRule
используя правило 1 выше - Уменьшить
constantExpression
вtestRule
используя правило 2 выше (negationExpression
в этом случае останется нетронутым, поэтому стек разбора будет выглядеть так:negationExpression testRule
)
Однако предупреждения не выдаются, и когда я смотрю на файл.output, который генерирует Bison, кажется, что двусмысленности нет:
state 5
6 testRule: constantExpression .
$default reduce using rule 6 (testRule)
...
state 9
5 testRule: negationExpression constantExpression .
$default reduce using rule 5 (testRule)
Согласно документам Bison:
Конфликт уменьшения / уменьшения возникает, если есть два или более правил, которые применяются к одной и той же последовательности ввода.
Разве это не тот случай здесь?
1 ответ
Нет, это не относится здесь.
"Последовательность ввода" - неудачное выражение; что на самом деле означает "тот же ввод", или, возможно, более явно, "та же самая последовательность префикса допустимого ввода". Другими словами, если есть два или более правил, которые могут применяться ко всему вводу, вплоть до текущей точки чтения (и принимая во внимание прогноз).
В вашей грамматике testRule
никогда ничего не следует Это и negationExpression
) можно уменьшить только в самом начале какого-либо вывода. Так что, если (частично уменьшенный) вход заканчивается negationExpression constantExpression
, невозможно уменьшить constantExpression
в testRule
потому что никакой вывод начального символа не может включать testRule
в не начальной позиции.