Приоритет и ассоциативность приложения функции 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 и т. д. и хотел бы знать, возможно ли дать expexp высший приоритет и оставил ассоциировать его.

Я разместил это на другом форуме для моего класса и получил:

Вы можете связать фиктивный токен с правилами приложения функции следующим образом:

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 ассоциативность и приоритетность делкакаций должны быть чрезвычайно сложны для понимания, за исключением простых случаев.

Другие вопросы по тегам