2011-08-30 52 views
2

是否有可能得到「積極」 ANTLR規則從一個動作方法被調用?取得積極ANTLR的規則

喜歡的東西了在ANTLR中,僞碼這本記錄功能,應該表現出的一些規則的開始和結束位置不拱手$開始和$結束的令牌與每個日誌() - 撥打:

@members{ 
    private void log() { 
    System.out.println("Start: " + $activeRule.start.pos + 
         "End: " + $activeRule.stop.pos); 
    } 
} 

expr: multExpr (('+'|'-') multExpr)* {log(); } 
    ; 

multExpr 
    : atom('*' atom)* {log(); } 
    ; 

atom: INT 
    | ID {log(); } 
    | '(' expr ')' 
    ; 

回答

0

不,無法獲取解析器當前所在規則的名稱。實現解析器規則默認情況下只是返回void的Java方法。從Java方法來看,畢竟在運行時找不到它的名字(當在這個方法中的時候)。

如果你在你的語法的options { ... }設置output=AST,每一個解析器規則創建(返回)一個ParserRuleReturnScope稱爲retval的一個實例:所以你使用,對於您的目的:

// ... 

options { 
    output=AST; 
} 

// ... 

@parser::members{ 
    private void log(ParserRuleReturnScope rule) { 
    System.out.println("Rule: " + rule.getClass().getName() + 
         ", start: " + rule.start + 
         ", end: " + rule.stop); 
    } 
} 

expr: multExpr (('+'|'-') multExpr)* {log(retval);} 
    ; 

multExpr 
    : atom('*' atom)*     {log(retval);} 
    ; 

atom: INT 
    | ID        {log(retval);} 
    | '(' expr ')' 
    ; 
// ... 

這然而,這不是一件非常可靠的事情:變量的名稱可能會在下一版ANTLR中發生很大變化。

+1

謝謝你的幫助!我會在開始和結束標記之後將@ after操作傳遞給log()函數。 – Sonson

+0

@Sonson,不客氣。是的,這是一個更好的選擇(在規則的'@after {...}'塊中的log方法中傳遞'getStart()'和'getEnd()':比使用局部變量' retval'。 –

+0

我也這麼做 - 請參閱http://stackoverflow.com/questions/12892122/how-to-merge-two-asts,但是'stop'和'getTree()'總是返回null :-( – j3d