3

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

我有一个问题,我理解它为什么不起作用,但我不确定如何解决它。

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

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()最终会变成“( Expression() )”,因此第三个和第二个选项都可以以左括号标记开头。

但是,我不确定如何解决这个问题。我之前在解析器中解决了一个类似的问题,但是由于Expression() --> Term() --> 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

上述方法将失败,因为它需要使用第三种替代方法,但是由于 '(' 导致解析器调用第二种替代方法,它无法访问它。

4

2 回答 2

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 返回的类型是布尔值。

于 2015-04-30T18:47:45.703 回答
1

您可以通过语法展望来解决这个问题。

void CompOp() : {} { <EQUAL_CHECK> | <NOT_EQUAL> | <LESS> | <LESS_EQUAL> | <GREATER> | <GREATER_EQUAL> }

void Condition() : {}{
        <NOT> Condition()
    |
        LOOKAHEAD(Expression() CompOp()) 
        Expression()
        CompOp()
        Expression()   
    |
        <OPEN_PARENTHESIS>
        Condition()
        (<AND> | <OR>)
        Condition()
        <CLOSE_PARENTHESIS>
}

更有效的是仅在存在(.

void Condition() : {}{
        <NOT> Condition()
    |   LOOKAHEAD( <OPEN_PARENTHESIS> )
        (
            LOOKAHEAD(Expression() CompOp()) 
            Expression()
            CompOp()
            Expression() 
        |
            <OPEN_PARENTHESIS>
            Condition()
            (<AND> | <OR>)
            Condition()
            <CLOSE_PARENTHESIS>
        )
    |
        Expression()
        CompOp()
        Expression()   
}
于 2015-04-30T18:50:08.503 回答