Reduce-reduce conflict

Jan 21, 2014 at 2:00 PM
I am currently working on some pseudoMDX expression parser and I got stucked.
I got reduce-reduce conflict which I don't know why occurs.

Here is my simplified grammar:
internal class CG : Grammar
{
    public CG()
        : base(false)
    {
        //terminals 
        var integer = new NumberLiteral("integer", NumberOptions.IntOnly);
        var mdxIdentifier = new StringLiteral("mdxIdentifier");
        mdxIdentifier.AddStartEnd("[", "]", StringOptions.None);

        //nonTerminals
        var expression = new NonTerminal("expression");
        var numOperation = new NonTerminal("numOperation");
        var numOperator = new NonTerminal("numOperator");
        var expressionItem = new NonTerminal("expressionItem");
        var memberFromExpression = new NonTerminal("memberFromExpression");
        var memberForItemFunction = new NonTerminal("memberForItemFnc");
        var member = new NonTerminal("member");
        var itemFunction = new NonTerminal("itemFunction");

        expression.Rule =
            numOperation
            | expressionItem
            | "(" + expression + ")";

        numOperation.Rule = expression + numOperator + expression;
        numOperator.Rule = ToTerm("+") | "-" | "/" | "*";
        expressionItem.Rule =
            memberFromExpression
            //| lots of other rules
            ;

        memberFromExpression.Rule =
            member
            | "{" + memberFromExpression + "}"
            | "(" + memberFromExpression + PreferShiftHere() + ")"
            //lots of other rules
            ;

        memberForItemFunction.Rule =
            member
            | "{" + memberForItemFunction + "}"
            //lots of other rules
            ;
            
        member.Rule =
            mdxIdentifier
            | itemFunction
            //lots of other rules
            ;

        itemFunction.Rule =
            memberForItemFunction + "." + "item" + "(" + integer + ")"
            //| memberFromExpression + "." + "item" + "(" + integer + ")"
            ;

        Root = expression;

        RegisterOperators();
    }

    private void RegisterOperators()
    {
        RegisterOperators(40, "+", "-");
        RegisterOperators(50, "*", "/");
    }
}
I can't catch the point why there is conflict.
  Reduce-reduce conflicts on inputs: }
  Reduce items:
    membersFromExpression -> member · [EOF + - / * } )]
    memberForItemFunction -> member · [. }]
  Transitions: 
Well, OK they may look the same i.e. "{[Member]}", but thy both exist in different context so I don't think they are ambigious.
Using Reduce hint wont help because
memberForItemFunction.Rule =
            member + ReduceHere()
            | "{" + memberForItemFunction + "}"
            //lots of other rules
            ;
would not parse expression like "{[Member]}" as memberFromExpression.
And using Reduce hint for memberFromExpression would not parse expression "{[Member]}.item(7)" because it would not identify "{[Member]}" as memberForItemFunction.

It there any way how to solve this?
Coordinator
Jan 22, 2014 at 6:57 PM
These two look so similar that it does not seem reasonable to make them different things for parser. Just define one thing instead, let parser parse it and then distinguish them if needed analyzing the parse tree. Note that LALR parser in general is very limited in recognizing 'surrounding context' of a token and making judgement about proper variety of a node - mostly, just the next token and nothing else in decision. Do not overload parser with semantic decisions - it things are similar the way they look, they should be represented as one element in the grammar.
Roman
Jan 23, 2014 at 6:35 AM
Well, thats the problem. The script above is only very simplified grammar and other rules for memberFromExpression and memberForItemFunction are different. This is the only case which causes a problem.
All in all, thnx for ansver, I'll try to reorganize it somehow.