I'm attempting to write my own programming language at the moment, and I have the following simplified grammar:
...
%%
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 ")";
%%
...
However, when I attempt to generate the C++ parser, I get a single reduce/reduce conflict.
$ 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
Here is the relevant section of the produced parser.output
file:
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)
And here is a screenshot of the counterexample, which shows that the issue is an ambiguity between lambda expressions and parenthesized identifiers.
In my language, I'd like to be able to support the following syntax. I think I understand the issue, but I'm having difficulty resolving the reduce/reduce conflict.
let x = 1
let foo = (x) // `foo` is the same type as `x`
let bar = (y) -> y + 1 // `bar` is a function
Could someone please tell me what I need to do to get it working, or point me to some resources that will help me figure it out?