我正在开发一个使用 OCaml 和 Menhir 作为解析器和词法分析器的编译器。当我编写像语法这样的 JavaScript 时,(a, b) => a + b
像 lambda 函数定义以及(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) }
在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) }
...
但这会在编译时出现reduce/reduce错误:
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
(one-arg-function)。但我仍然不明白为什么它仍然会产生这个错误,因为对我来说非常清楚,后面跟着一个粗箭头的括号=>
将成为一个函数......
有人可以帮助我吗?