我试图制作一个没有运算符优先级的语法,但要求你使用一个运算符或将它们括在括号中。 (为简单起见,使用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;
答案 0 :(得分:1)
您可能需要查看How to remove global backtracking from your grammar。
模糊性在于expr
的两种选择都可以以bexpr
开头。你需要摆脱这种模糊性。关键在于观察+
仅在没有括号的情况下发生,如果它是整个表达式。所以我们最终得到:
expr : operand ('+' operand)?;
operand : '(' expr ')' | 'test';
换句话说:如果运算符表达式作为操作数出现,那么它必须括在括号中。