2011-05-17 47 views
2

我寫了一個ANTLR3語法細分成更小的規則以提高可讀性。 例如:如何避免使用ANTLR3構建中間體和無用的AST節點?

messageSequenceChart: 
    'msc' mscHead bmsc 'endmsc' end 
; 

# Where mscHead is a shortcut to : 
mscHead: 
    mscName mscParameterDecl? timeOffset? end 
    mscInstInterface? mscGateInterface 
; 

我知道內置ANTLR AST建築功能允許聲明不會在最後的AST中間AST節點的用戶。但是如果你手動建立AST呢?

messageSequenceChart returns [msc::MessageSequenceChart* n = 0]: 
    'msc' mscHead bmsc'endmsc' end 
    { 
    $n = new msc::MessageSequenceChart(/* mscHead subrules accessors like $mscHead.mscName.n ? */ 
             $bmsc.n); 
    } 
; 

mscHead: 
    mscName mscParameterDecl? timeOffset? end 
; 

該文檔沒有談論這樣的事情。所以看起來我必須爲每個中間規則創建節點才能訪問其子規則結果。

有誰知道更好的解決方案?

謝謝。

回答

2

你可以讓你的分治(S)解決了這個返回多個值和訪問只有那些你感興趣的。

下面的演示展示瞭如何做到這一點。雖然它不是在C,我相信,你就可以對其進行調整,使其適合您的需要:

grammar Test; 

parse 
    : sub EOF {System.out.printf("second=\%s\n", $sub.second);} 
    ; 

sub returns [String first, String second, String third] 
    : a=INT b=INT c=INT 
    { 
     $first = $a.text; 
     $second = $b.text; 
     $third = $c.text; 
    } 
    ; 

INT 
    : '0'..'9'+ 
    ; 

SPACE 
    : ' ' {$channel=HIDDEN;} 
    ; 

如果你的解析與生成的解析器輸入"12 34 56"second=34打印到控制檯,你可以運行後看到:

import org.antlr.runtime.*; 

public class Main { 
    public static void main(String[] args) throws Exception { 
    TestLexer lex = new TestLexer(new ANTLRStringStream("12 34 56")); 
    TokenStream tokens = new TokenRewriteStream(lex); 
    TestParser parser = new TestParser(tokens); 
    parser.parse(); 
    } 
} 

所以,從像$sub.INT,或$sub.$aparse規則快捷方式訪問三個INT令牌之一,在可能的,很遺憾。

+0

太棒了!有用 ! :D你讓我省了很多時間! – 2011-05-17 20:27:23

+0

@Julio,很高興聽到,歡迎您。 – 2011-05-17 21:04:56

+0

另一個問題! http://stackoverflow.com/questions/6047127/ignore-tokens-in-the-token-characters我相信你:p – 2011-05-18 15:22:18