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

Antlr 如何在不使用backtrack=true的情况下解决此问题?,antlr,antlr3,ll,Antlr,Antlr3,Ll,我试图创建一个没有运算符优先级的语法,但要求要么使用一个运算符,要么将它们括在括号中。(为了简单起见,这里使用test代替id | int_literal等和+代替有效运算符列表)。例如: test + test ///valid! (test + test) + test ///valid! (test + test) + (test + test) /// valid! test + test + test /// invalid! 是否有任何方法可以编写不需要backtrack=true

我试图创建一个没有运算符优先级的语法,但要求要么使用一个运算符,要么将它们括在括号中。(为了简单起见,这里使用
test
代替
id | int_literal等
+
代替有效运算符列表)。例如:

test + test ///valid!
(test + test) + test ///valid!
(test + test) + (test + test) /// valid!
test + test + test /// invalid!
是否有任何方法可以编写不需要backtrack=true的语法?我认为左因子分解在这里没有什么意义,我也不确定一个语法谓词会有什么帮助

以下是我所拥有的(需要
backtrack=true
):

你可能想看看

模糊之处在于
expr
的两个备选方案都可以从
bexpr
开始。你需要消除这种模糊性。关键在于观察到,
+
如果是整个表达式,则只会在没有括号的情况下出现。因此,我们最终得出以下结论:

expr : operand ('+' operand)?;
operand : '(' expr ')' | 'test';
换句话说:如果运算符表达式作为操作数出现,则必须将其括在括号中。

您可能需要查看

模糊之处在于
expr
的两个备选方案都可以从
bexpr
开始。你需要消除这种模糊性。关键在于观察到,
+
如果是整个表达式,则只会在没有括号的情况下出现。因此,我们最终得出以下结论:

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

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

但是有没有办法在不重复“+”的情况下实现这一点?当运算符较多时,长列表重复两次会变得很难看。仅供参考,您在问题中的语法不允许
(test)
。我知道。但这很简单,可以添加。但事实上,这要好得多。谢谢。但是有没有办法在不重复“+”的情况下做到这一点呢?当运算符较多时,长列表重复两次会变得很难看。仅供参考,您在问题中的语法不允许
(test)
。我知道。但这很简单,可以添加。但事实上,这要好得多。非常感谢。