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

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

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

rule:   ....   %precc DUMMY_FUN_APP

Затем укажите ассоциативность, используя %left и фиктивный токен.

Но я не совсем уверен, что это значит, поэтому, если бы кто-то мог уточнить это или дать мне другое решение, это было бы здорово.


person Anatoliy Sokolov    schedule 16.02.2016    source источник


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

person Jeffrey Scofield    schedule 16.02.2016
comment
В итоге я просто использовал версию с несколькими выражениями, да, я использовал yacc - person Anatoliy Sokolov; 16.02.2016