简体   繁体   English

Antlr4:同时处理优先级和左侧递归

[英]Antlr4: dealing with priority and left-side recursion at the same time

I'm writing a language parser in Antlr4. 我正在用Antlr4编写语言解析器。 I'm already quite well versed with it, but I don't want to fall into a pitfall (again), so here it is: 我已经非常熟悉它,但是我不想再次陷入陷阱,所以这里是:

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

and the input: 和输入:

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

The tree I obtain is: 我得到的树是:

(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)
        )
    )
)

(An expression of logical comparison, where left-hand-side is user.field, comparator is == and right-hand-side is the ternary operator.) (逻辑比较的表达式,其中左侧为user.field,比较器为==,右侧为三元运算符。)

The actual result should be a ternary operator, where gate expression is a logical comparison. 实际结果应该是三元运算符,其中gate表达式是逻辑比较。

How can I fix it? 我该如何解决? I was certain, that the fact I placed TernaryExpression above LogicalComparisonExpression will suffice, but apparently it doesn't. 我确定,将TernaryExpression放在LogicalComparisonExpression之上的事实就足够了,但是显然不是。

Ok, here is the workaround. 好的,这是解决方法。 I don't like it, but it seems to work for some reason. 我不喜欢它,但似乎出于某种原因而起作用。

In expression rule, changed 在表达规则上,已更改

|   expression logicalComparator expression # LogicalComparisonExpression

to

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

I placed only two items in operator=(...) for testing purposes. 为了测试目的,我只在operator =(...)中放置了两个项目。

This has some negative effects though: 但是,这有一些负面影响:

  1. inline definition of operators <- I'd love to have them separate for readability. 内联运算符的定义<-我希望将它们分开以提高可读性。
  2. forces me to tokenize '==' instead of '=' '='. 强迫我标记化'=='而不是'=''='。 If I try: 如果我尝试:

    operator=(EQUALS EQUALS | LSHARP) 运算符=(EQUALS EQUALS | LSHARP)

I get "label assigned to a block which is not a set". 我得到“标签分配给不是集合的块”。

I guess I'll work with this, but I'd still to see if it can be done better. 我想我会解决这个问题,但是我仍然想看看是否可以做得更好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM