我目前正在尝试编写自己的编程语言,并且我有以下简化的语法:
...
%%
prog: stmtlist | %empty;
block: "{" stmtlist "}";
stmtlist: stmtlist ";" stmt | stmt;
decllist: decllist "," decl | decl;
exprlist: exprlist "," expr | expr;
stmt: stmt_decl;
stmt_decl
: "let" decllist "=" exprlist
| "let" decllist
;
decl: IDENTIFIER ":" IDENTIFIER | IDENTIFIER;
expr: expr_function;
expr_function
: "(" decllist ")" "->" expr_function
| "(" decllist ")" "->" block
| "(" ")" "->" expr_function
| "(" ")" "->" block
| expr_additive
;
expr_additive
: expr_additive "+" expr_primary
| expr_additive "-" expr_primary
| expr_primary
;
expr_primary: INTVAL | FLTVAL | IDENTIFIER | "(" expr ")";
%%
...
但是,当我尝试生成 C++ 解析器时,我遇到了一个 reduce/reduce 冲突。
$ bison -v -Werror -l --defines=parser.hh -o parser.cc parser.yy
parser.yy: error: 1 reduce/reduce conflict [-Werror=conflicts-rr]
parser.yy: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples
这是生成的parser.output
文件的相关部分:
State 27 conflicts: 1 reduce/reduce
...
State 27
13 decl: "identifier" • ":" "identifier"
14 | "identifier" •
26 expr_primary: "identifier" •
":" shift, and go to state 11
"+" reduce using rule 26 (expr_primary)
"-" reduce using rule 26 (expr_primary)
")" reduce using rule 14 (decl)
")" [reduce using rule 26 (expr_primary)]
$default reduce using rule 14 (decl)
这是反例的屏幕截图,它表明问题在于 lambda 表达式和带括号的标识符之间的歧义。
用我的语言,我希望能够支持以下语法。我想我理解这个问题,但我很难解决减少/减少冲突。
let x = 1
let foo = (x) // `foo` is the same type as `x`
let bar = (y) -> y + 1 // `bar` is a function
有人可以告诉我我需要做什么才能使其正常工作,或者向我指出一些可以帮助我解决问题的资源吗?