涉及两次扩展的选择冲突:

时间:2015-04-30 17:18:33

标签: java parsing javacc left-recursion

我正在尝试创建自己的分析器/解析器。

我遇到一个问题,我明白为什么它不起作用,但我不确定如何解决它。

这是解析器问题部分的代码。

void Expression() : {}{
    Term() ((<PLUS> | <MINUS>) Term())*
}

void Term() : {}{
     Factor()((<MULTIPLY> | <DIVIDE>) Factor())*
}

void Factor() : {}{
    (<ID> | <NUMBER> | ((<PLUS> | <MINUS>)?<OPEN_PARENTHESIS> Expression() <CLOSE_PARENTHESIS>))
}

void Condition() : {}{
    (
        (<NOT> Condition()) |
        (<OPEN_PARENTHESIS> Condition() (<AND> | <OR>) Condition() <CLOSE_PARENTHESIS>) |
        (Expression() (<EQUAL_CHECK> | <NOT_EQUAL> | <LESS> | <LESS_EQUAL> | <GREATER> | <GREATER_EQUAL>) Expression())     
    )
}

如您所见,问题来自OR部分中三个选项中最后两个选项的 Condition()方法。这是因为 Expression()最终可以成为&#34;( Expression())&#34;因此,第三个和第二个选项都可以以开括号括号开头。

但是,我不确定如何解决这个问题。我在解析器的早期解决了类似的问题但是我不能在这里采用相同的逻辑而不会因为 Expression() - &gt;的方式而非常混乱。 Term() - &gt; Factor(),问题代码在 Factor()方法中一直向下。

非常感谢任何建议。

谢谢,

托马斯。

编辑:

有关详细信息,我将提供应该使用此解析器的代码示例,但由于上面解释的错误而不会。

fun succesful_method()
    start
        var i = 1;
        if(i > 0 and i < 2)
        do
            i = 2;
        stop
    stop

start
    successful_method()
stop

上面的方法会成功运行,因为它使用 Condition()方法的第二种方法。

fun succesful_method()
    start
        var i = 1;
        if(i > 0)
        do
            i = 2;
        stop
    stop

start
    successful_method()
stop

上述方法会失败,因为它需要使用第三种方法,但由于&#39;(&#39;导致解析器调用第二种方法,因此无法访问此方法。

1 个答案:

答案 0 :(得分:1)

对所有表达式使用单个语法并为所有运算符定义优先级应解决您的问题,但代价是为表达式类型添加语义检查。

Expr -> AndExpr (<OR> AndExpr)*
AndExpr -> NotExpr (<AND> NotExpr)*
NotExpr -> <NOT>* RelExpr
RelExpr -> NumExpr () (<RELOP> NumExpr)?

NumExpr -> Term ((<PLUS>|<MINUS>) Term)*
Term -> Factor ((<MULTIPLY>|<DIVIDE>) Factor)*
Factor -> (<PLUS>|<MINUS>)* Atom
Atom -> <ID> | <NUMBER> | <OPEN_PARENTHESIS> Expr <CLOSE_PARENTHESIS>

令牌<RELOP>代表您的关系运营商。

请注意,这个语法让你混合布尔值和数值表达式,所以你应该检查错误。

例如对于Expr -> AndExpr,返回的类型将是AndExpr的类型。但是对于AndExpr <OR> AndExpr,您应该检查两个AndExprs是否为布尔表达式,并且Expr返回的类型将是布尔值。