Приоритет и ассоциативность приложения функции OCaml
Мне нужно дать высокий приоритет и оставить ассоциативность для функции приложения в моем анализаторе 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 и фиктивный токен.
Но я не совсем уверен, что это значит, так что если кто-то мог бы уточнить это или дать мне другое решение, которое было бы замечательно.
1 ответ
Вы не говорите, какой генератор парсера вы используете. Если вы используете 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
ассоциативность и приоритетность делкакаций должны быть чрезвычайно сложны для понимания, за исключением простых случаев.