I'm working on a compiler using OCaml and Menhir as parser and lexer. When I'm writing a JavaScript like Grammar, with (a, b) => a + b
like lambda function definition and also arithmetics (a + b) * c
with parenthesis prioritizing sub-expressions, I write
expr
: x = ID { EId(x) }
...
| LPAREN; e = expr; RPAREN; { e }
...
| LPAREN; args = separated_list(COMMA, ID); RPAREN; ARROW; body = expr; { EFunction(args, body) }
in parser.mly
.
Just adding few more context, I have my lexer.mll
like this:
let letter = ['a'-'z' 'A'-'Z']
let lud = ['a'-'z' 'A'-'Z' '_' '0'-'9']
let id = letter lud*
rule read = parse
...
| "(" { LPAREN }
| ")" { RPAREN }
| "," { COMMA }
| "=>" { ARROW }
...
| id { ID (Lexing.lexeme lexbuf) }
...
But this is going to get a reduce/reduce error when compile:
Error: do not know how to resolve a reduce/reduce conflict between the following two productions:
expr -> ID
separated_nonempty_list(COMMA,ID) -> ID
I know that the problem is probably caused by the ambiguity between these two: (a)
and (a) => a
(one-arg-function). But I still couldn't understand why it is still producing this error since to me it is super clear that the parenthesis followed by a fat arrow =>
is going to be a function...
Can someone help me a bit on this?