0

我使用 fsyacc(用于 fsharp 的 yacc)来编写一个小型解析器。语法类似于

Expr:=
  | INT                              { Cst $1           }  
  | Expr PLUS  Expr                     { Op("+", $1, $3) }  
  | Expr TIMES Expr                     { Op("*", $1, $3) }

然后,在没有声明优先级或关联性的情况下,我将“1 * 2 + 3”解析为

Op ("*",Cst 1,Op ("+",Cst 2,Cst 3)

为什么?

4

1 回答 1

2

如果您没有在您描述的模棱两可的语法中声明标记的优先级和关联性,默认情况下,yacc 将解决由此产生的移位/减少冲突,如果移位。这具有使规则右递归的效果,因此运算符将出现从右到左分组。

如果您确实定义了优先级规则,它们所做的是解决移位/减少冲突以支持更高的优先级(令牌或规则),或者如果优先级相同,则支持 shift for%right和 reduce for %left。这基本上就是优先级设置所做的所有事情,因此它们有时可用于以与“优先级”无关的方式解决冲突,如果这是您想要做的。但是对于简单的中缀表达式语法,它们基本上完全按照您的意愿行事。

于 2020-08-19T19:47:49.450 回答