"Reduce-reduce" errors eat my lunch; we really need some context on them

Apr 25, 2013 at 9:31 PM
"Reduce-reduce conflict. State S0, lookaheads: EOF LF. Selected reduce on first production in conflict set. (S0)"

My grammar file is only 170 lines long, but I still have absolutely no idea where to even start with an error like this. Can we put the nearest non-terminal name in the error somewhere?

Also, I thought Irony treated EOF as an alternate for LF if I used this: LanguageFlags |= LanguageFlags.NewLineBeforeEOF. Is that not true? Why would it have a conflict between the two?
Coordinator
Apr 26, 2013 at 5:13 PM
well sorry for your lunch, but - don't quite get what's the problem with the conflict? did you try to double-click on conflict message in Grammar Explorer? It will bring you to the state printout, which show you all.
About NewLineBeforeEOF - this has no impact on parser construction. It is at runtime, when parsing, the scanner injects NewLine before sending EOF to parser, just to adjust for source files that have no final line-break, but the language is line-based.
Apr 26, 2013 at 8:33 PM
Edited Apr 26, 2013 at 8:34 PM
Here is the output from Grammar Explorer. I assume that I look in the "Reduce Items" section, but I don't know what to look for there.
State S0 (Inadequate)
  Reduce-reduce conflicts on inputs: EOF LF
  Shift items:
    Program' -> ·Program EOF 
    Program -> ·StartSection.grp1 
    StartSection.grp1 -> ·StartSectionRow.grp1+ 
    StartSectionRow.grp1+ -> ·StartSectionRow.grp1+ StartSectionRow.grp1 
    StartSectionRow.grp1+ -> ·StartSectionRow.grp1 
    StartSectionRow.grp1 -> ·OptionalTelemetryTriples.grp1 LF 
    OptionalTelemetryTriples.grp1 -> ·TelemetryTriples.grp1 
    TelemetryTriples.grp1 -> ·Telemetry 
    Telemetry -> ·until Unnamed0 Telemetry.Operator Telemetry.Value OptionalMetric 
    TelemetryTriples.grp1 -> ·Telemetry 
    Telemetry -> ·until Unnamed1 Telemetry.Operator Telemetry.Value OptionalMetric 
    StartSectionRow.grp1 -> ·ActionTriplet.grp1 OptionalTelemetryTriples.grp1 LF 
    ActionTriplet.grp1 -> ·ActionSetTriples.grp1 
    ActionSetTriples.grp1 -> ·Action 
    Action -> ·set Unnamed2 at Action.Value OptionalMetric 
    ActionSetTriples.grp1 -> ·Action 
    Action -> ·set Unnamed3 at Action.Value OptionalMetric 
    ActionTriplet.grp1 -> ·ActionIncTriples.grp1 
    ActionIncTriples.grp1 -> ·Action 
    Action -> ·inc Unnamed4 by Action.Value OptionalMetric 
    ActionIncTriples.grp1 -> ·Action 
    Action -> ·inc Unnamed5 by Action.Value OptionalMetric 
    ActionTriplet.grp1 -> ·ActionDecTriples.grp1 
    ActionDecTriples.grp1 -> ·Action 
    Action -> ·dec Unnamed6 by Action.Value OptionalMetric 
    ActionDecTriples.grp1 -> ·Action 
    Action -> ·dec Unnamed7 by Action.Value OptionalMetric 
    ActionTriplet.grp1 -> ·ActionMulTriples.grp1 
    ActionMulTriples.grp1 -> ·Action 
    Action -> ·mul Unnamed8 by Action.Value OptionalMetric 
    ActionMulTriples.grp1 -> ·Action 
    Action -> ·mul Unnamed9 by Action.Value OptionalMetric 
    Program -> ·StartSection.grp2 
    StartSection.grp2 -> ·StartSectionRow.grp2+ 
    StartSectionRow.grp2+ -> ·StartSectionRow.grp2+ StartSectionRow.grp2 
    StartSectionRow.grp2+ -> ·StartSectionRow.grp2 
    StartSectionRow.grp2 -> ·OptionalTelemetryTriples.grp2 LF 
    OptionalTelemetryTriples.grp2 -> ·TelemetryTriples.grp2 
    TelemetryTriples.grp2 -> ·Telemetry 
    Telemetry -> ·until Unnamed10 Telemetry.Operator Tail OptionalMetric 
    TelemetryTriples.grp2 -> ·Telemetry 
    Telemetry -> ·until Unnamed11 Telemetry.Operator Telemetry.Value OptionalMetric 
    StartSectionRow.grp2 -> ·ActionTriplet.grp2 OptionalTelemetryTriples.grp2 LF 
    ActionTriplet.grp2 -> ·ActionSetTriples.grp2 
    ActionSetTriples.grp2 -> ·Action 
    Action -> ·set Unnamed12 at Action.Value OptionalMetric 
    ActionTriplet.grp2 -> ·ActionIncTriples.grp2 
    ActionIncTriples.grp2 -> ·Action 
    Action -> ·inc Unnamed13 by Action.Value OptionalMetric 
    ActionTriplet.grp2 -> ·ActionDecTriples.grp2 
    ActionDecTriples.grp2 -> ·Action 
    Action -> ·dec Unnamed14 by Action.Value OptionalMetric 
    ActionTriplet.grp2 -> ·ActionMulTriples.grp2 
    ActionMulTriples.grp2 -> ·Action 
    Action -> ·mul Unnamed15 by Action.Value OptionalMetric 
  Reduce items:
    StartSection.grp1 -> · [EOF]
    OptionalTelemetryTriples.grp1 -> · [LF]
    StartSection.grp2 -> · [EOF]
    OptionalTelemetryTriples.grp2 -> · [LF]
  Transitions: Program->S1, StartSection.grp1->S2, StartSectionRow.grp1+->S3, StartSectionRow.grp1->S4, OptionalTelemetryTriples.grp1->S5, TelemetryTriples.grp1->S6, Telemetry->S7, until->S8, Telemetry->S9, ActionTriplet.grp1->S10, ActionSetTriples.grp1->S11, Action->S12, set->S13, Action->S14, ActionIncTriples.grp1->S15, Action->S16, inc->S17, Action->S18, ActionDecTriples.grp1->S19, Action->S20, dec->S21, Action->S22, ActionMulTriples.grp1->S23, Action->S24, mul->S25, Action->S26, StartSection.grp2->S27, StartSectionRow.grp2+->S28, StartSectionRow.grp2->S29, OptionalTelemetryTriples.grp2->S30, TelemetryTriples.grp2->S31, Telemetry->S32, Telemetry->S33, ActionTriplet.grp2->S34, ActionSetTriples.grp2->S35, Action->S36, ActionIncTriples.grp2->S37, Action->S38, ActionDecTriples.grp2->S39, Action->S40, ActionMulTriples.grp2->S41, Action->S42
Coordinator
Apr 26, 2013 at 8:55 PM
my guess is that you have several optional sections, optionally (!) included, and parser does not know how to interpret an empty file. To say more, I need to see the grammar
Apr 26, 2013 at 9:45 PM
Thanks for the clue! I've got it all figured out. Here's a little documentation for anyone else dealing with Reduce-Reduce errors:

You can only have one of each RValue (right-hand side of the arror value) in the "Reduce Items" section. If you have more than one it can't decide which non-terminal to use in a given scenario. (It likely doesn't matter which one gets used; I guess Irony doesn't want to take any chances.)

This won't work as all child trees support an Empty:
foreach(var group in groups)
{
   ....
   var myRule = ....;
   myRule.Rule = MakeStarRule(myRule, eachRowOfMyRule);

   if(program.Rule == null)
       program.Rule = myRule;
   else program.Rule |= myRule;
}
You have to do it like this instead:
foreach(var group in groups)
{
   ....
   var myRule = ....;
   if(program.Rule == null)
      myRule.Rule = MakeStarRule(myRule, eachRowOfMyRule);
   else
      myRule.Rule = MakePlusRule(myRule, eachRowOfMyRule);

   if(program.Rule == null)
       program.Rule = myRule;
   else program.Rule |= myRule;
}