2012-11-21 89 views
1

我試圖寫一段語法來表達的層次結構字段訪問,像ABC其中Ç場ABbaANTLR:現場訪問和評估

評價的a.b.c.d.e我們需要評估A.B.C.D的值,然後得到Ë價值的價值。 要evalutate值ABCD,我們需要evalute ABC的值,然後得到d的價值等等...

如果你有一個這樣的樹(箭頭指「 lhs是rhs的父親「):

Node(e) -> Node(d) -> Node(c) -> Node(b) -> Node(a) 

評價很簡單。使用遞歸,我們只需要解決孩子的價值,然後訪問正確的領域。

的問題是:我有這樣3條規則,我ANTLR語法文件:

tokens { 
    LBRACE = '{' ; 
    RBRACE = '}' ; 
    LBRACK = '[' ; 
    RBRACK = ']' ; 
    DOT  = '.' ; 
    .... 
} 

reference 
    : DOLLAR LBRACE selector RBRACE -> ^(NODE_VAR_REFERENCE selector) 
; 

selector 
    : IDENT access -> ^(IDENT access) 
; 

access 
    : DOT IDENT access? -> ^(IDENT<node=com.at.cson.ast.FieldAccessTree> access?) 
    | LBRACK IDENT RBRACK access? -> ^(IDENT<node=com.at.cson.ast.FieldAccessTree> access?) 
    | LBRACK INTEGER RBRACK access? -> ^(INTEGER<node=com.at.cson.ast.ArrayAccessTree> access?) 
; 

正如預期的那樣,我的樹有這種形式:

ReferenceTree 
    IdentTree[a] 
    FieldAccessTree[b] 
     FieldAccessTree[c] 
     FieldAccessTree[d] 
      FieldAccessTree[e] 

的評價不那麼容易在另一種情況,因爲我需要得到當前節點的值,然後把它給孩子,等等......

有沒有什麼辦法來扭轉使用ANTLR的樹的順序或我需要做的它手動?

+0

因此,'a.b.c'應該產生'^(c ^(b a))'。輸入'a [1] [2] [3]'的AST應該如何顯示? –

+0

正確。與數組訪問相同的表單:^(3 ^(2 ^(1 a))) – Antonio

回答

1

您只能使用內嵌樹運算符,^而不是重寫規則來做到這一點。

的演示:

grammar T; 

options { 
    output=AST; 
} 

tokens { 
    ROOT; 
    LBRACK = '[' ; 
    RBRACK = ']' ; 
    DOT = '.' ; 
} 

parse 
: selector+ EOF -> ^(ROOT selector+) 
; 

selector 
: IDENT (access^)* 
; 

access 
: DOT IDENT    -> IDENT 
| LBRACK IDENT RBRACK -> IDENT 
| LBRACK INTEGER RBRACK -> INTEGER 
; 

IDENT : 'a'..'z'+; 
INTEGER : '0'..'9'+; 
SPACE : ' ' {skip();}; 

解析輸入:

a.b.c a[1][2][3] 

將產生以下AST:

enter image description here


有關內聯樹運算符和重寫規則的更多信息,請參閱:How to output the AST built using ANTLR?

+0

很好的答案,它的工作原理相當不錯。謝謝。 – Antonio

+0

不客氣@Antonio。 –