Skip to content

Help understanding syntax error with non-terminal, ok with terminal #12

@InfinitiesLoop

Description

@InfinitiesLoop

Here's a complete repro if the issue I'm trying to resolve. The output will be:
Error:Syntax error, expected: > ((1:10))

If all you do is comment out the line marked fails and uncomment the line marked succeeds, the expression parses successfully.

There's an ambuguity with "<" in that it might be part of an 'infix' expression or the beginning of a part of a 'componentAccess' expression, but I expected Irony to work it out since the componentAccess rule won't be met, whereas infix is. It seems to be able to do that when the infixOp is removed as a non-terminal and a pure terminal used instead.

Either this indicative of a bug or I just need help understanding this behavior, and whether or not its possible to have a grammar parsed successfully this way. I've played with grammar hints to no avail. This is a simplified version of the actual grammar I'm using, for demonstration purposes.

    class Program
    {
        static void Main(string[] args)
        {
            Try("abc < xyz");

            Console.ReadLine();
        }

        private static void Try(string expr)
        {
            var p = new Parser(new ExpressionGrammar());
            var result = p.Parse(expr);
            Console.WriteLine(result.Status + ":" + string.Join("\n", result.ParserMessages.Select(m => $"{m.Message} ({m.Location})")));
        }

        public class ExpressionGrammar : Grammar
        {
            public ExpressionGrammar() : base(false)
            {
                var formula = new NonTerminal("formula");
                var infix = new NonTerminal("infix");
                var infixOp = new NonTerminal("infixOp");
                var componentAccess = new NonTerminal("componentaccess");
                var identifier = new NonTerminal("identifier");

                Root = formula;

                formula.Rule =
                    identifier
                    | componentAccess
                    | infix
                    ;

                identifier.Rule = ToTerm("abc") | ToTerm("xyz");
                infixOp.Rule = ToTerm("<");
                // e.g.: abc<xyz>.abc
                componentAccess.Rule = formula + "<" + identifier + ">" + "." + identifier;

                // fails
                infix.Rule = formula + infixOp + formula;
                // succeeds (inlining infixOp)
                //infix.Rule = formula + ToTerm("<") + formula;
            }
        }
    }

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions