2013-11-04 66 views
0

我正在Antlr4中編寫語言分析器。我已經用它相當精通,但我不想陷入一個陷阱(再一次),所以在這裏它是: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上面的事實就足夠了,但顯然它沒有。

+0

一些額外的研究,我發現後: https://github.com/antlr/antlr4/issues/303 https://github.com/antlr/antlr4/issues/268 這似乎表明,該問題出在Antlr上... – Gerino

回答

0

好的,這是解決方法。我不喜歡它,但它似乎因某種原因而起作用。

在表達式規則,改變

| expression logicalComparator expression # LogicalComparisonExpression 

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

我置於只有兩個在操作者用於測試目的的物品=(...)。

這雖然有一些負面影響:運營商<的

  1. 直列定義 - 我很想讓他們分開的可讀性。
  2. 強迫我標記'=='而不是'=''='。如果我嘗試:

    運算符=(等號EQUALS | LSHARP)

我得到 「標籤分配給塊,不是一套」。

我想我會與此合作,但我仍然要看看它是否可以做得更好。