2010-04-20 51 views
1

我目前有一個編譯器,它使用一個代碼塊的所有子代都在同一級別的AST(即,block.children == {stm1,stm2,stm3 ,等...})。我試圖在這棵樹上做活性分析,這意味着我需要從stm1處理返回的值,然後將其傳遞給stm2,然後將stm2返回的值傳遞給stm3,依此類推。當AST以這種方式構建時,我沒有看到以這種方式執行子規則的方式。一次處理一個n-ary ANTLR AST一個孩子

有沒有辦法允許我用給定的AST鏈接兒童語法項目的執行,還是我將不得不經歷重構解析器以生成嵌套結構和更新其餘部分的痛苦過程編譯器的工作與新的AST?


例ANTLR語法片段:

block 
    : ^(BLOCK statement*) 
    ; 
statement 
    : // stuff 
    ; 

我希望我不用去:

block 
    : ^(BLOCK statementList) 
    ; 
statementList 
    : ^(StmLst statement statement+) 
    | ^(StmLst statement) 
    ; 
statement 
    : // stuff 
    ; 

回答

1

分析器(或詞法)規則,可以採取參數值和能返回一個值。所以,在你的話,你可以這樣做:

block 
@init {Object o = null; /* initialize the value being passed through */ } 
    : ^(BLOCK (s=statement[o] {$o = $s.returnValue; /*re-assign 'o' */ })*) 
    ; 

statement [Object parameter] returns [Object returnValue] 
    : // do something with 'parameter' and 'returnValue' 
    ; 

這裏是一個非常簡單的例子,你可以用它來玩弄:

grammar Test; 

@members{ 
    public static void main(String[] args) throws Exception { 
     ANTLRStringStream in = new ANTLRStringStream("1;2;3;4;"); 
     TestLexer lexer = new TestLexer(in); 
     CommonTokenStream tokens = new CommonTokenStream(lexer); 
     TestParser parser = new TestParser(tokens); 
     parser.parse(); 
    } 
} 

parse 
    : block EOF 
    ; 

block 
@init{int temp = 0;} 
    : (i=statement[temp] {temp = $i.ret;} ';')+ 
    ; 

statement [int param] returns [int ret] 
    : Number {$ret = $param + Integer.parseInt($Number.text);} 
    {System.out.printf("param=\%d, Number=\%s, ret=\%d\n", $param, $Number.text, $ret);} 
    ; 

Number 
    : '0'..'9'+ 
    ; 

當你生成一個解析器和詞法分析器從它並編譯這些類,執行TestParser類,你會看到下面的內容印在你的控制檯上:

param=0, Number=1, ret=1 
param=1, Number=2, ret=3 
param=3, Number=3, ret=6 
param=6, Number=4, ret=10 
+0

非常感謝。這正是我需要的。 – 2010-04-21 14:47:13

+0

好聽@Chris。別客氣。 – 2010-04-21 16:02:39