我需要在我的OCaml解析器中为函数应用程序赋予高优先级和左关联性。我有一堆匹配的不同标记,例如
%token LET REC EQ IN FUN ARROW
%token IF THEN ELSE
%token PLUS MINUS MUL DIV LT LE NE AND OR
%token LPAREN RPAREN
我使用%left
,right
给出了所有这些优先级和关联性...
但是,由于我用来匹配的exp
不是令牌,我想知道在这种情况下我会怎么做:
exp:
| exp exp { App($1,$2)}
我拥有exp
的所有匹配,没有制作一堆不同的exp1 exp2s等等,想知道是否有可能给exp
exp
最高优先权并离开关联它。
我把它发布在我班上的另一个论坛上,并得到了:
您可以将虚拟标记与功能应用程序规则关联,如下所示:
rule: .... %precc DUMMY_FUN_APP
然后使用%left和虚拟标记指定关联性。
但我不确定这意味着什么,如果有人可以详细说明或给我另一个很好的解决方案。
答案 0 :(得分:0)
您不会说出您正在使用的解析器生成器。如果您正在使用ocamlyacc,您可能会查看OCaml的实际语法以获取想法。你可以在这里找到语法:https://github.com/ocaml/ocaml/blob/trunk/parsing/parser.mly
在parser.mly
中,令牌按优先顺序从低到高列出。一些令牌是虚拟令牌,仅列出用于建立优先权的令牌。然后使用%prec token_name
在语法规则中引用这些标记。
以下是令牌列表的最后几行:
%nonassoc below_SHARP
%nonassoc SHARP /* simple_expr/toplevel_directive */
%nonassoc below_DOT
%nonassoc DOT
/* Finally, the first tokens of simple_expr are above everything else. */
%nonassoc BACKQUOTE BANG BEGIN CHAR FALSE FLOAT INT INT32 INT64
LBRACE LBRACELESS LBRACKET LBRACKETBAR LIDENT LPAREN
NEW NATIVEINT PREFIXOP STRING TRUE UIDENT
请注意,虚拟标记below_SHARP
具有非常高的优先级。
以下是功能应用的相关规则:
expr:
| simple_expr simple_labeled_expr_list
{ mkexp(Pexp_apply($1, List.rev $2)) }
simple_labeled_expr_list:
labeled_simple_expr
{ [$1] }
| simple_labeled_expr_list labeled_simple_expr
{ $2 :: $1 }
labeled_simple_expr:
simple_expr %prec below_SHARP
{ ("", $1) }
对于它的价值,除了简单的情况外,我总是发现yacc
关联性和优先级延迟非常难以理解。