如何在不使用backtrack = true的情况下解决此问题?

时间:2012-05-07 01:49:11

标签: antlr antlr3 ll

我试图制作一个没有运算符优先级的语法,但要求你使用一个运算符或将它们括在括号中。 (为简单起见,使用test代替id|int_literal etc+而不是有效运算符列表。例如:

test + test ///valid!
(test + test) + test ///valid!
(test + test) + (test + test) /// valid!
test + test + test /// invalid!

有没有办法为此编写一个不需要backtrack = true的语法?我不认为左分解在这里真的有意义,而且我不确定句法谓词是如何帮助的。

这里有我所拥有的(需要backtrack=true):

fragment
bexpr : 'test' | '(' cbebr ')';

fragment
cbexpr : bexpr '+' bexpr;

expr : bexpr | cbexpr;

1 个答案:

答案 0 :(得分:1)

您可能需要查看How to remove global backtracking from your grammar

模糊性在于expr的两种选择都可以以bexpr开头。你需要摆脱这种模糊性。关键在于观察+仅在没有括号的情况下发生,如果它是整个表达式。所以我们最终得到:

expr : operand ('+' operand)?;
operand : '(' expr ')' | 'test';

换句话说:如果运算符表达式作为操作数出现,那么它必须括在括号中。