2012-08-06 92 views
2

我有一個規則,我想拆分,因爲我想在其他規則中重複使用相同的子規則。原始版本正常工作:如何在ANTLR中重寫一個節點的子節點?

type 
    : (basicType -> basicType) 
    ('*' -> ^(TYPE_POINTER basicType) 
    | '[' ']' -> ^(TYPE_DYN_ARRAY basicType) 
    | '[' IntegerLiteral ']' -> ^(TYPE_STATIC_ARRAY IntegerLiteral basicType) 
    | '[' IntegerLiteral '..' IntegerLiteral ']' -> ^(REF_TYPE_SLICE IntegerLiteral IntegerLiteral basicType) 
    | '[' type ']' -> ^(TYPE_MAP_ARRAY type basicType) 
)? 
    ; 

此規則使得能夠採取正常類型(basicType,其可以是一個參考或主類型,如int,炭等。)和地點下一個不同AST節點,它使它成爲指針,數組等等。這在C語言中是非常普遍的事情。

但是,如果我分裂這樣的:

basicType2 
    : '*' -> ^(TYPE_POINTER) 
    | '[' ']' -> ^(TYPE_DYN_ARRAY) 
    | '[' IntegerLiteral ']' -> ^(TYPE_STATIC_ARRAY IntegerLiteral) 
    | '[' IntegerLiteral '..' IntegerLiteral ']' -> ^(REF_TYPE_SLICE IntegerLiteral IntegerLiteral) 
    | '[' type ']' -> ^(TYPE_MAP_ARRAY type) 
    ; 

type 
    : (basicType -> basicType) 
    (basicType2 -> ^(basicType2 basicType))? 
    ; 

一切看起來不錯,解析將不受影響,但在AST的basicType2的孩子卻完全喪失了。對於TYPE_STATIC_ARRAY或REF_TYPE_SLICE或TYPE_MAP_ARRAY,只有根將被複制到類型的上方,但子節點缺失。

我調試瞭解析器代碼,並且在我看來,CommonTree類的複製構造函數在不復制子項時調用,只有令牌和源範圍信息。有什麼辦法可以將CommonTree節點和它的子節點一起放到另一個重寫規則的頂部?

回答

2

始終使用單一標記爲一棵樹的根:另一棵樹,因爲你與basicType2做:

type 
    : (basicType -> basicType) 
    (basicType2 -> ^(basicType2 basicType))? 
    ; 

試試這個:

grammar ... 

options { ... } 

tokens { T2; } 

... 

type 
    : (basicType -> basicType) 
    (basicType2 -> ^(T2 basicType2 basicType))? 
    ; 

... 
+0

雖然我看看這是如何工作的,但不幸的是,這不會產生與第一(運作)規則相同的AST。它將生成一個T2節點,其中basicType2和basicType作爲子節點。我想要的是,如果basicType2存在,那麼basicType應該是子節點,這是basicNode2的新增子項。但是,謝謝...我想到了這一點,因爲在第二種形式中,它將basicType2作爲僅具有令牌的節點對待,而不是作爲子樹。 – progician 2012-08-06 12:11:32

+1

@progician,是的,我知道它會改變你的樹,但是,因爲'basicType2'可以是一個帶有根節點和子節點的AST,'^(basicType2 basicType)'不起作用。如果'basicType2'總是會產生一個單一的標記,'^(basicType2 basicType)'*會起作用。 – 2012-08-06 16:35:29

相關問題