为lambda表达式编写解析器,
data expr = Symbol of string | Lambda of string * expr | App of expr * expr在编写.mly文件时,我如何表示一个表达式序列
e1 e2 e3 e4 应该被解析为
App ((App (App e1 e2) e3) e4)使用规则:
%public expr_expr:
| ID { Symbol ($1) }
| NUMBER { Symbol ($1) }
| LPAREN expr_expr RPAREN { ($2) }
| LAMBDA ID ARROW expr_expr { Lambda ($2, $4) }
| expr_expr expr_expr { Apply ($1, $2) }给出了结构(e1 , (e2 , (e3 , e4))),而不是(((e1, e2), e3), e4)。是否有一种方法来控制规则的相联性而不是象征性?
发布于 2016-12-18 07:58:51
免责声明:我使用的是ocamlyacc,而不是menhir,所以我的答案是基于前者。AFAIUI,后者是向后兼容的,所以我假设我的答案可能是有用的。
引用文档http://caml.inria.fr/pub/docs/manual-ocaml/lexyacc.html
规则还可以在右侧部分包含%prec符号指令,以覆盖规则的默认优先级和关联性以及给定符号的优先级和相联性。
所以我会试着
%left Application要使规则保持关联(在定义先例的地方;您至少需要定义应用程序和lambda抽象的相对优先级),然后将规则更改为
| expr_expr expr_expr { Apply ($1, $2) } %prec Application这使得Application成为一个虚拟符号,仅用于分配结合性和优先级。
注1:以上部分是我的猜测。显然,我从来没有(成功)自己尝试过这样的方法。当我有一次写lambda语法时,我通过修改语法来增强联想性。
注2:如果它不像上面那样工作,您可以查看一下OCaml源代码。OCaml语言对于应用程序具有相同的语法。
https://stackoverflow.com/questions/41203991
复制相似问题