3

据我在互联网上搜索可以弄清楚,看起来Camlp5(以前的Camlp4)使用递归下降解析器,而ocamlyacc基于LALR的解析器生成器。

在 LALR 解析器生成器中,优先级和关联性被映射到移位/减少冲突。我的问题是像 Camlp5 这样的递归下降解析器如何处理声明性运算符优先级?

 # let expr = Grammar.Entry.create gram "expr";;
 # EXTEND
     expr:
       [ "add" LEFTA
         [ x = expr; "+"; y = expr -> x + y
         | x = expr; "-"; y = expr -> x - y ]
       | "mult" RIGHTA
         [ x = expr; "*"; y = expr -> x * y
         | x = expr; "/"; y = expr -> x / y ]
       | "simple" NONA
         [ x = INT -> int_of_string x
         | "("; e = expr; ")" -> e ] ]
     ;
   END;;

它如何处理左递归调用?camlp5 (camlp4) 是否使用表驱动的运算符优先级方法:https ://en.wikipedia.org/wiki/Operator-precedence_parser

非常感谢任何有关 Camlp4 解析器内部工作的见解或链接。

4

1 回答 1

0

Recursive Descent Parser不像 LALR 那样是表驱动的解析器。解析器做出的决定被硬编码在函数体中(每个规则都是一个函数)。实际上,将语法定义CamlpN 编译为一组相互递归函数。这里的获胜点是您不需要手动编写此功能。因此,如果您更改语法,您只需更新语法定义,所有必要的功能都会为您更新。在常规的手工编码递归解析器中,您需要自己更新它,这很容易出错。

于 2015-08-31T15:11:38.280 回答