Help with shift-reduce conflicts in simple grammar

Oct 19, 2014 at 2:45 PM
I'm trying to make a grammar but I keep getting shift-reduce conflicts and I'm struggling to interpret the output to work out why. I've looked at samples provided with Irony and other examples online and I'm still stuck. Some valid examples of the strings that I'm trying to parse are:
  • A
  • A_B
  • A_B_C_D_E
  • A(true)_B
  • A_B(1)_C
  • A_B(C=1)_D
  • A(B=1&C=2)_D
My grammar is currently defined as:
             // Terminals
            var integer = new NumberLiteral("integer", NumberOptions.IntOnly);
            var constant = new ConstantTerminal("constant", typeof(bool));
            constant.Add("true", true);
            constant.Add("false", false);
            var identifier = new IdentifierTerminal("identifier");

            // Non-Terminals
            var documentParameter = new NonTerminal("documentParameter");
            var root = new NonTerminal("root");
            var intermediate = new NonTerminal("intermediate");
            var terminator = new NonTerminal("terminator");
            var intermediateList = new NonTerminal("intermediateList");
            var rootRestriction = new NonTerminal("rootRestriction");
            var intermediateRestriction = new NonTerminal("intermediateRestriction");
            var expression = new NonTerminal("expression");
            var expressionList = new NonTerminal("expressionList");
            var relationalOperator = new NonTerminal("relationalOperator");
            var logicalOperator = new NonTerminal("logicalOperator");

            // Keywords
            KeyTerm underscore = ToTerm("_", "underscore");

            // Rules
            relationalOperator.Rule = "=";
            logicalOperator.Rule = "&";
            expression.Rule = identifier + relationalOperator + integer;
            expressionList.Rule = MakePlusRule(expressionList, logicalOperator, expression);

            rootRestriction.Rule = "(" + (integer | expressionList | constant) + ")";
            intermediateRestriction.Rule = "(" + (integer | expressionList) + ")";

            root.Rule = identifier + rootRestriction.Q() + underscore;
            intermediate.Rule = identifier + intermediateRestriction.Q() + underscore;
            intermediateList.Rule = MakeStarRule(intermediateList, intermediate);
            terminator.Rule = identifier;

            documentParameter.Rule = (root + intermediateList).Q() + terminator;

            RegisterOperators(80, relationalOperator);
            RegisterOperators(70, logicalOperator);
            MarkPunctuation("_", "(", ")");
            Root = documentParameter;
This produces 3 shift-reduce conflicts. If I try to parse the simplest example "A" then I get an error saying it expects "(" or "_" but shouldn't the (root + intermediateList).Q() mean they're optional? Any help on what I'm misunderstanding and where I'm going wrong would be much appreciated.
Oct 19, 2014 at 3:34 PM
After playing a bit more I've realised that IdentifierTerminal allows underscores (which I should have known immediately) by default and I can remove them. Still getting some shift-reduce conflicts but I'm making progress now at least.