【问题标题】:How can I resolve this without using backtrack=true?如何在不使用 backtrack=true 的情况下解决此问题?
【发布时间】:2012-05-07 01:49:10
【问题描述】:

我正在尝试制作一种没有运算符优先级的语法,但要求您使用一个运算符或将它们括在括号中。 (为简单起见,使用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;

【问题讨论】:

    标签: antlr antlr3 ll


    【解决方案1】:

    你可能想看看How to remove global backtracking from your grammar

    歧义在于expr 的两个替代项都可以以bexpr 开头。你需要摆脱这种歧义。关键在于观察到 + 只有在它是整个表达式时才出现不带括号的情况。所以我们最终得到:

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

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

    【讨论】:

    • 但是有没有办法做到这一点,而无需重复'+'?当有更多的操作符时,长列表重复两次就很难看。
    • 仅供参考,您在问题中的语法不允许(test)
    • 我知道。但这很简单,可以添加。但这实际上要好得多。谢谢。
    猜你喜欢
    • 2017-05-23
    • 1970-01-01
    • 1970-01-01
    • 2019-10-29
    • 2020-08-17
    • 2020-12-20
    • 2023-03-15
    • 1970-01-01
    • 2021-10-11
    相关资源
    最近更新 更多