为什么会有冲突,因为前递增和后递减的优先级和结合性已经在语法中明确指定了?
下面是为lemon解析器生成器编写的语法:
%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
您只定义了伪终结符(PostDecrementation和prerementation)的优先级规则。在任何地方都没有定义实际的终端递减的优先级。
优先级总是在生产(可以减少)和终端(可以移动)之间进行比较。因此,您需要指定递减的优先级来解决冲突。
我个人不会在这种情况下使用优先级声明。但是如果你真的想这样做,你可能应该只使用一个伪终结符,并让递减作为使用它的两个结果之一的优先级。