b3b00/csly

`BuildParser` returns null on non-LL1 grammar

recolic opened this issue · 4 comments

I'm building a POC for a naive script language, and this is my syntax:

          int ::= DIGITS
          string ::= LITERAL_STRING
          expr ::= int | string
          expr ::= expr OP_PLUS expr
          expr ::= expr OP_MINUS expr
          expr ::= expr OP_MULTIPLY expr

I'm running ParserBuilder.BuildParser and it returns null without any error message. I don't know where should I investigate.

I think that, the LL_RECURSIVE_DESCENT parser doesn't support non-LL1 grammar, like expr ::= expr + expr.

This is my minimal reproduce: https://git.recolic.net/msc/parser-poc/-/blob/master/lytest/RnLangNaiveParser.cs, and the error point is here: https://git.recolic.net/msc/parser-poc/-/blob/master/lytest/Program.cs#L14

b3b00 commented

Hello, CSLY is recursive descent parser, so it CAN NOT be used for left recursive grammars (see about left recursion )

But BuildParser should return an error stating the left recursion.

I'm quite busy right now, will to look at it, as sson as i got 5 minutes.

For now you should look expression parsing to define your arithmetic expression parser.

Hi,
Thanks for the information... I'm trying to make it support something like this:

function("args") + function("args")
// expr + expr

So I can not write rules like this : expr ::= int + expr..

b3b00 commented

There is no problem i think. Here is a simple unit test that I wrote to check it . you can take inspiration for your case :
Tell me if it's ok for you.

        [Fact]
        public static void Issue251LeftrecForBNF() {
            ParserBuilder<Issue251Parser.Issue251Tokens,Issue251Parser.ExprClosure> builder = new ParserBuilder<Issue251Parser.Issue251Tokens, Issue251Parser.ExprClosure>();
            Issue251Parser instance = new Issue251Parser();
            var bres = builder.BuildParser(instance,ParserType.LL_RECURSIVE_DESCENT, "expr");
            Assert.False(bres.IsOk);
            Assert.Equal(1,bres.Errors.Count);
            var error = bres.Errors.First();
            Assert.Equal(ErrorCodes.PARSER_LEFT_RECURSIVE, error.Code);
        }

and you should definitely use the expression parsing feature to build your expression parser.

Oh I got it.

My problem is that, builder.BuildParser() is not returning null, but I'm directly using its .result. That's why it's null.