0

我正在用 Bison 用 C 语言编写一个解析器,虽然它似乎在我迄今为止尝试过的所有情况下都能正常工作,但我的二元运算符(以及我的一元 NOT 运算符作为出色地)。

binary_op :
      PLUS { }
      | MINUS { }
      | TIMES { }
      | SLASH { }
      | POWER { }
      | AND { }
      | OR { }
      | LE { }
      | LT { }
      | GE { }
      | GT { }
      | EQ { }
      | NE { }
      | MOD { }
    ;

unary_op :
    NOT { }
    ;

expr :
    ...
    | unary_op expr { }
    | expr binary_op expr { }

当我通过 bison --verbose 运行我的 .y 文件时,我看到:

state 51
   11 set_existence: expr . IN set
   12              | expr . NOT IN set
   34 expr: expr . binary_op expr
   34     | expr binary_op expr .

   ...
   NOT    shift, and go to state 26
   AND    shift, and go to state 27
   OR     shift, and go to state 28
   ....
   NOT     [reduce using rule 34 (expr)]
   AND     [reduce using rule 34 (expr)]
   OR      [reduce using rule 34 (expr)]

我没有看到任何实际解析二进制运算符的问题,但似乎我应该无论如何都应该解决移位/减少问题。我不知道冲突在哪里—— set_existence 产生似乎完全不相关。我最好的猜测(在黑暗中拍摄)是它可能与 EQ 用作二元运算符(相等比较)以及赋值(例如,“foo = bar = baz;”将设置根据 bar 和 baz 是否相等,将 foo 设置为 true/false)。如果我将相等比较更改为 == ("foo = bar==baz;"),我的解析器会按预期运行,但仍然存在相同的移位/减少冲突。

编辑:我确实指定了关联性:

%left OR
%left AND
%left NOT
%left LT LE GT GE NE EQ
%left PLUS MINUS
%left TIMES MOD SLASH
%left POWER
4

1 回答 1

2

有几种方法可以避免这种情况。第一种是使用%left,%right%nonassoc命令来指定优先级(参见手册)。

我个人更喜欢的另一种选择是将优先级直接编码到语法中。例如,这是一个简单算术表达式的 BNF:

expr ::= term | expr + term
term ::= factor | term * factor
factor ::= number | ( expr )

这消除了语法级别的模棱两可的解析。

于 2010-10-05T00:36:01.020 回答