I am trying to solve shift/reduce conflict in Bison. I have following grammar rules
new_expr:
T_NEW class_name_reference optional_generics_list ctor_arguments
{ $$ = zend_ast_create(ZEND_AST_NEW, $2, $4, $3); }
| T_NEW anonymous_class
{ $$ = $2; }
optional_generics_list:
/* empty */ { $$ = NULL; }
| generics_list { $$ = $1; }
ctor_arguments:
/* empty */ { $$ = zend_ast_create_list(0, ZEND_AST_ARG_LIST); }
| argument_list { $$ = $1; }
The problem here lies in that fact, that both optional_generics_list and ctor_arguments can be empty. How can I specify (if I could) that if both optional_generics_list and ctor_arguments are empty, then ctor_arguments should have higher priority. Or maybe my question is not correct, and how can solve this conflict instead.
Some updated info: Maybe output of generated .output file will help:
State 156 conflicts: 1 shift/reduce
State 156:
303 new_expr: "new (T_NEW)" class_name_reference . optional_generics_list ctor_arguments
'<' shift, and go to state 304
'<' [reduce using rule 168 (optional_generics_list)]
$default reduce using rule 168 (optional_generics_list)
optional_generics_list go to state 305
generics_list go to state 306
State 305
303 new_expr: "new (T_NEW)" class_name_reference optional_generics_list . ctor_arguments
'(' shift, and go to state 229
$default reduce using rule 405 (ctor_arguments)
argument_list go to state 546
ctor_arguments go to state 552
State 306
169 optional_generics_list: generics_list .
$default reduce using rule 169 (optional_generics_list)
generics_list
andargument_list
look the same? Or, more precisely, is there some terminal which could be the start of either one? – Fourscoregenerics_list
must start with<
? Or can it be empty? (If it can be empty, it's obvious that the grammar is ambiguous.) Although I suspect the problem is with what can follow anew_expr
: if the next token could be a(
, for example, it won't be clear to the parser if that parenthesis belongs to anargument_list
or not. (And then it has nothing to do with generics). – Fourscore