I'm trying to write a parser for tiny Visual Basic language. And I can't resolve next shift/reduce conflict. I have these rules:
simple_type_name:
qualified_type_name
| primitive_type_name;
qualified_type_name:
ID
| qualified_type_name PERIOD ID;
primitive_type_name: BOOLEAN|CHAR|STRING|BYTE|SBYTE|USHORT|SHORT|UINTEGER|INTEGER|ULONG|LONG|SINGLE|DOUBLE;
Bison says me:
simple_type_name -> qualified_type_name . (rule 20)
qualified_type_name -> qualified_type_name . PERIOD ID (rule 23)
PERIOD shift, and go to state 41
PERIOD [reduce using rule 20 (simple_type_name)]
$default reduce using rule 20 (simple_type_name)
So, what is the right solution in this conflict?
You must have some other rule in the grammar where
simple_type_name
is followed by aPERIOD
. Something like:perhaps?
The problem is that it needs more lookahead to determine if what comes after the
PERIOD
is a simpleID
that makes this a qualified type name or something else that would make it a simple type name.One possible solution (impossible to tell, as you don't show enough of your grammar) is to unfactor
simple_type_name
where it is followed by a period -- duplicate the rule, replacingsimple_type_name
with bothqualified_type_name
andprimitive_type_name
. With the aboveexpression
example, that would be:Depending on the rest of your grammar it might be necessary or desirable to completely unfactor
simple_type_name
, replacing all mentions of it with duplicated rules and deleting thesimple_type_name
rule itselfedit
Ok, you've linked more of your grammar, so we can see that the problematic use of
simple_type_name
is in a trailing context (at the end of the rhs of a rule), so simple unfactoring is not enough. You may be able to fix it by repeated unfactoring (unfactorsimple_type_name
as described above, then unfactorsimple_expression
and/ortype_name
as well). The goal is to push the unfactoring to a rule that hason the right side, and replace that with rules
where
other-nonterminal
is a duplicate ofsome-nonterminal
with the rules that lead to a singlequalified_type_name
removed.Unfortunately this can easily lead to an exponential blowup in the size of the grammar, so may be impractical. In that case the only option may be to use a more powerful parsing method, such as bison's
%glr-parser
option or backtracking with btyacc.