picoe / Eto.Parse

Recursive descent LL(k) parser for .NET with Fluent API, BNF, EBNF and Gold Grammars
MIT License
148 stars 30 forks source link

Grammer's inner parser set to empty #60

Closed ykafia closed 2 years ago

ykafia commented 2 years ago

Hi,

have I an error where the Inner parser of the Grammar i'm creating is transformed to an EmptyParser by this function during the Match.

Here's a sample of the grammar I wrote

public class CalculatorGrammar : Grammar
{
    public CalculatorGrammar() : base("calc")
    {
        EnableMatchEvents = false;
        CaseSensitive = true;

        var ws = new RepeatCharTerminal(char.IsWhiteSpace);

        var ldu = LetterOrDigit | "_";
        var identifier = LetterOrDigit.Then(ldu.Repeat().Optional()).WithName("Identifier");

        var lbr = Set("{");
        var rbr = Set("}");

        var floatParser = new NumberParser{AllowSign = true, AllowDecimal = true, AllowExponent = true,ValueType = typeof(double), Name = "ConstantDouble", AddMatch = true, AddError = true};
        var intParser = new NumberParser{AllowSign = true, AllowDecimal = false, AllowExponent = false, ValueType = typeof(long), Name = "ConstantInteger", AddMatch = true, AddError = true};
        var boolParser = new BooleanTerminal{CaseSensitive = true, TrueValues = new string[]{"true"}, FalseValues = new string[]{"false"}, AddError = true, AddMatch = true, Name = "ConstantBoolean"};

        var constants = floatParser.Or(intParser).Or(boolParser).WithName("Constant"); 

        var primary_expr = identifier.Or(constants).WithName("PrimaryExpression");

        var assign = identifier.Then(Set("=")).Then(primary_expr).WithName("AssignExpression");
        assign.SeparateChildrenBy(ws);

        var parenthesis_expr = new SequenceParser();
        parenthesis_expr.Add(
            primary_expr.WithName("NoParens")
            .Or(
                Set("(").Then(parenthesis_expr).Then(")").WithName("Parens")
            )
        );
        parenthesis_expr.WithName("ParenthesisExpression");
        parenthesis_expr.SeparateChildrenBy(ws);

        var mul_expr = new SequenceParser();

        mul_expr.Add(
            parenthesis_expr.WithName("NoMult")
            .Or(
                mul_expr.Then("*").Then(mul_expr).WithName("Mult")
            )
        );
        mul_expr.WithName("MultExpression");
        mul_expr.SeparateChildrenBy(ws);

        Inner = mul_expr;

    }
}

I don't yet understand the source but would be very happy to have any direction to solve the issue/contribute to this project

ykafia commented 2 years ago

I think i solved it :

mul_expr.Add(
            parenthesis_expr.WithName("NoMult")
            .Or(
                // This one should be parenthesis_expr, or else it creates an infinite recursion
                **mul_expr**.Then("*").Then(mul_expr).WithName("Mult")
            )
        );