Search code examples
ocamlgrammaryaccocamlyacc

On ocamlyacc, function application grammar and precedence


I'm OCaml newbie and I'm trying to write a simple OCaml-like grammar, and I can't figure this out. My grammar allows something like this:

let sub = fun x -> fun y -> x - y;;

However, if I want to use the function so defined, I can write: (sub 7) 3 but I can't write sub 7 3, which really bugs me. For some reason, it gets interpreted as if I wrote sub (7 3) (which would treat 7 as a function with argument 3). The relevant sections are:

/* other operators, then at the very end: */
%left APPLY

/* ... */

expr:
    /* ... */
    | expr expr %prec APPLY      { Apply($1, $2) }

Thanks!


Solution

  • The ocaml compiler does function application as follows: (from ocaml/parsing/parser.mly)

    expr:
    ...
      | simple_expr simple_labeled_expr_list
          { mkexp(Pexp_apply($1, List.rev $2)) }
    

    where simple_expr is a subset of the possible expr values that can evaluate to a function without needing parentheses. This excludes all the non-self-bracketed constructs from being used inline with a function call. It also clarifies the associativity of the subexpressions, as the second subexpression is explicitly a list.

    As to why your attempt to use %left APPLY to get the correct associativity doesn't work, from the comments in 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.
    

    I'd say this means that you can't use %prec for associativity without an operator. Try creating the associativity you want through defining more rules, and see where that leads.