`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
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
..
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.