2011-04-08 99 views
0

什麼是最快(較小的代碼)的方式來獲得語法樹?ANTLR:得到語法樹的最快方法是什麼?

我正在嘗試獲取語法樹。我根據我的簡單的語法生成的C#代碼:

grammar MyPascal; 
options 
{ 
    language=CSharp3; 
    output=AST; 
} 

operator: (block | ID); 
block : BEGIN operator* END; 
BEGIN :'begin'; 
END  :'end'; 
ID  :('a'..'z')+; 
WS  :(' ' 
     | '\t' 
     | '\r' 
     | '\n' 
     ) {$channel=HIDDEN;}; 

當使用ANTLR我'可以用於簡單輸入文本,如:

input.txt: 
begin 
    abs 
    qwe 
    begin 
    begin 
    end 
    end 
end 

我得到語法樹的漂亮的圖片。

現在我想知道是否有任何簡單的方法從C#中獲取我的「程序」的樹結構,而無需編寫1000行代碼。

這裏我'想獲得語法樹:

class Program 
{ 
    static void Main(string[] args) 
    { 
     MyPascalLexer lex = new MyPascalLexer(new ANTLRFileStream(@"M:\input.txt")); 
     CommonTokenStream tokens = new CommonTokenStream(lex); 
     MyPascalParser g = new MyMyPascalParser(tokens); 
     MyPascalParser.myprogram_return X = g.myprogram();          
     Console.WriteLine(X.Tree); // Writes: nill 
     Console.WriteLine(X.Start); // Writes: [@0,0:4='begin',<4>,1:0] 
     Console.WriteLine(X.Stop); // Writes: [@35,57:57='end',<19>,12:2] 
    } 
} 

回答

1

你必須「告訴」 ANTLR建立一個AST,反對令牌只是一個扁平流(簡單的解析樹)。

請參閱this SO Q&A,它顯示瞭如何在C#中執行此操作。

而且,你不應該使用:

ID : ('a'..'z')*; 

即:讓詞法規則匹配一個空字符串,這可能(?甚至會)給你帶來麻煩(它總是匹配!)。您需要讓它至少匹配一個字符:

ID : ('a'..'z')+; 
+0

您說得對。在提出緊湊尺寸的問題之前,我已經削減了一些。我已經修復了這些錯誤。 – Astronavigator 2011-04-08 16:22:38

+0

:)我在這個鏈接中找到了我的問題的答案。所以我接受你的答案。正如我在一個例子中添加了兩行:1:使用Antlr.Runtime.Tree; 2:CommonTree Tree =(CommonTree)Q.Tree;它的工作原理:) – Astronavigator 2011-04-08 17:01:14

+0

@Astronavigator,不客氣,很高興聽到你找到解決你的問題。 – 2011-04-08 17:18:35