我试图在JavaCC中删除expr的左递归,应将其定义为:
expr ::= statement binary_op statement
| **(** expr **)**
| identifier **(** arg **)**
| statement
此代码在我的程序中导致左递归:
void expr() : { }
{
< LPAREN > simpleExpr() < RPAREN >
| < IDENTIFIER > <LPAREN > arg() < RPAREN >
| statement()
}
void simpleExpr() : { }
{
statement() binary_op() statement()
}
语句定义为:
statement ::= id | - id | number | false | true | expr
void statement() : { }
{
< ID > | < NOT_OP > < ID >
| < DIGIT >
| < TRUE >
| < FALSE >
| expr()
}
我在程序中遇到的错误:
Left recursion detected: "expr... --> statement... --> expr..."
我该如何解决?
答案 0 :(得分:1)
根据您的语法,statement
可以是expr
,而expr
可以是statement
。因此,这两个非终结符生成的语言是相同的。您不需要两个非终结符。我建议删除statement
的定义,并将expr
的定义更改为此
void expr() : { }
{
< ID >
| < NOT_OP > < ID >
| < DIGIT >
| < TRUE >
| < FALSE >
| < LPAREN > simpleExpr() < RPAREN >
| < IDENTIFIER > <LPAREN > arg() < RPAREN >
}
然后选择
statement
的定义中)到处将expr
替换为simpleExpr
或添加以下规则:
void statement() : { }
{
expr()
}
答案 1 :(得分:0)
statement
的使用非常不寻常。它看起来更像是literal
。statement
中,应删除行| expr()
。否则,statement
可能是expression
,而expression
可能是statement
...解析器应该如何决定?