1

我正在用 Antlr4 编写语言解析器。我已经非常精通它了,但我不想(再次)陷入陷阱,所以这里是:

expression
    |   gate=expression QUESTION
            (ifTrue=expression)? COLON
            (ifFalse=expression)?               # TernaryExpression
    |   Identifier                              # IdentifierExpression
    |   literal                                 # LiteralExpression
    |   expression logicalComparator expression # LogicalComparisonExpression
    |   expression logicalOperator expression   # LogicalOperationExpression
    ;

和输入:

user.field == 'STRING' ? user.field + user.otherField : user.somethingElse

我得到的树是:

(expression
    (expression
        (expression user) . (expression field)
    )
    (logicalComparator = =)
    (expression
        (expression (literal 'STRING'))
        ? (expression
            (expression
                (expression user) . (expression field)
            )
            (binaryOperator +)
            (expression
                (expression user) . (expression otherField)
            )
        )
        : (expression
            (expression user) . (expression somethingElse)
        )
    )
)

(逻辑比较的表达式,其中左侧是 user.field,比较器是 ==,右侧是三元运算符。)

实际结果应该是一个三元运算符,其中门表达式是一个逻辑比较。

我该如何解决?我确信,我将 TernaryExpression 放在 LogicalComparisonExpression 之上的事实就足够了,但显然它没有。

4

1 回答 1

0

好的,这是解决方法。我不喜欢它,但它似乎出于某种原因工作。

在表达式规则中,已更改

|   expression logicalComparator expression # LogicalComparisonExpression

|   lhs=expression operator=(   DEQUALS
                                 |LSHARP
                             ) rhs=expression # LogicalComparisonExpression

出于测试目的,我只在 operator=(...) 中放置了两个项目。

虽然这有一些负面影响:

  1. 运算符的内联定义<-为了便于阅读,我希望将它们分开。
  2. 迫使我标记“==”而不是“=”“=”。如果我尝试:

    运算符=(等于 | LSHARP)

我得到“分配给不是集合的块的标签”。

我想我会处理这个,但我仍然想看看它是否可以做得更好。

于 2013-11-04T10:47:34.127 回答