与后缀/中缀操作符的优先级冲突



下面是为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)的优先级规则。在任何地方都没有定义实际的终端递减的优先级。

优先级总是在生产(可以减少)和终端(可以移动)之间进行比较。因此,您需要指定递减的优先级来解决冲突。

我个人不会在这种情况下使用优先级声明。但是如果你真的想这样做,你可能应该只使用一个伪终结符,并让递减作为使用它的两个结果之一的优先级。

相关内容

  • 没有找到相关文章

最新更新