Я работаю над компилятором, используя OCaml и Menhir в качестве парсера и лексера. Когда я пишу JavaScript, например Grammar, с (a, b) => a + b
определением лямбда-функции, а также арифметикой (a + b) * c
со скобками, отдающими приоритет подвыражениям, я пишу
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
.
Просто добавив еще несколько контекстов, у меня есть lexer.mll
вот так:
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) }
...
Но это приведет к ошибке уменьшения/уменьшения при компиляции:
Error: do not know how to resolve a reduce/reduce conflict between the following two productions:
expr -> ID
separated_nonempty_list(COMMA,ID) -> ID
Я знаю, что проблема, вероятно, вызвана неоднозначностью между этими двумя: (a)
и (a) => a
(функция с одним аргументом). Но я все еще не мог понять, почему он все еще выдает эту ошибку, поскольку для меня совершенно ясно, что скобка, за которой следует жирная стрелка =>
, будет функцией...
Может ли кто-нибудь помочь мне немного в этом?