Я - новичок OCaml, и я пытаюсь записать простую подобную OCaml грамматику, и я не могу понять это. Моя грамматика позволяет что-то вроде этого:
let sub = fun x -> fun y -> x - y;;
Однако, если я хочу использовать функцию, так определенную, я могу записать: (sub 7) 3
но я не могу записать sub 7 3
, который действительно прослушивает меня. По некоторым причинам это интерпретируется, как будто я записал sub (7 3)
(который рассматривал бы 7
как функция с аргументом 3
). Соответствующие разделы:
/* other operators, then at the very end: */
%left APPLY
/* ... */
expr:
/* ... */
| expr expr %prec APPLY { Apply($1, $2) }
Спасибо!
Компилятор ocaml выполняет функцию приложения следующим образом: (из ocaml/parsing/parser.mly
)
expr:
...
| simple_expr simple_labeled_expr_list
{ mkexp(Pexp_apply($1, List.rev $2)) }
где simple_expr
- это подмножество возможных значений expr, которые могут быть оценены в функцию без необходимости использования круглых скобок. Это исключает использование всех несамостоятельных конструкций, заключенных в скобки, в сочетании с вызовом функции. Это также проясняет ассоциативность подвыражений, поскольку второе подвыражение явно является списком.
Что касается того, почему ваша попытка использовать %left APPLY
для получения правильной ассоциативности не сработала, из комментариев в ocaml's parser.mly:
We will only use associativities with operators of the kind x * x -> x
for example, in the rules of the form expr: expr BINOP expr
in all other cases, we define two precedences if needed to resolve
conflicts.
Я бы сказал, что это означает, что вы не можете использовать %prec для ассоциативности без оператора. Попробуйте создать нужную вам ассоциативность, определив больше правил, и посмотрите, к чему это приведет.