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)
。我知道。但这很简单,可以添加。但事实上,这要好得多。非常感谢。