これがレモンパーサージェネレーター用に書かれた文法です:
%left PostDecrementation.
%right PreDecrementation.
program ::= expression.
expression ::= Terminal.
expression ::= unaryoperation.
unaryoperation ::= Decrementation expression. [PreDecrementation]
unaryoperation ::= expression Decrementation. [PostDecrementation]
コンパイルしようとすると、ジェネレーターは次の競合を生成します。
State 0:
program ::= * expression
expression ::= * Null
expression ::= * unaryoperation
unaryoperation ::= * Decrementation expression
unaryoperation ::= * expression Decrementation
Null shift 5
Decrementation shift 1
program accept
expression shift 2
unaryoperation shift 4
State 1:
expression ::= * Null
expression ::= * unaryoperation
unaryoperation ::= * Decrementation expression
unaryoperation ::= Decrementation * expression
unaryoperation ::= * expression Decrementation
Null shift 5
Decrementation shift 1
expression shift 3
unaryoperation shift 4
State 2:
(0) program ::= expression *
unaryoperation ::= expression * Decrementation
$ reduce 0
Decrementation shift 6
State 3:
(3) unaryoperation ::= Decrementation expression *
unaryoperation ::= expression * Decrementation
Decrementation shift 6
Decrementation reduce 3 ** Parsing conflict **
{default} reduce 3
State 4:
(2) expression ::= unaryoperation *
{default} reduce 2
State 5:
(1) expression ::= Null *
{default} reduce 1
State 6:
(4) unaryoperation ::= expression Decrementation *
{default} reduce 4
PreIncrementationとPostDecrementationの両方の優先順位と結合性が文法で明示的に指定されているのに、なぜ競合があるのですか?