2010-12-09 129 views
9

我有一個語法規則,ANTLR:獲取令牌名稱?

OR 
    : '|'; 

但是,當我打印使用AST,

public static void Preorder(ITree tree, int depth) 
{ 
    if (tree == null) 
    { 
     return; 
    } 

    for (int i = 0; i < depth; i++) 
    { 
     Console.Write(" "); 
    } 

    Console.WriteLine(tree); 

    for(int i=0; i<tree.ChildCount; ++i) 
     Preorder(tree.GetChild(i), depth + 1); 
} 

(感謝Bart)它顯示實際|字符。有沒有辦法讓我說「OR」呢?

回答

8

robert啓發此答案。

if (ExpressionParser.tokenNames[tree.Type] == tree.Text) 
    Console.WriteLine(tree.Text); 
else 
    Console.WriteLine("{0} '{1}'", ExpressionParser.tokenNames[tree.Type], tree.Text); 
6

幾周前我不得不這樣做,但是使用了Python ANTLR。它對你沒有多大幫助,但它可以幫助別人尋找答案。

使用Python ANTLR,令牌類型是整數。令牌文本包含在令牌對象中。下面是我所使用的溶液:

import antlrGeneratedLexer 

token_names = {} 
for name, value in antlrGeneratedLexer.__dict__.iteritems(): 
    if isinstance(value, int) and name == name.upper(): 
     token_names[value] = name 

有沒有明顯的邏輯到令牌的編號(至少與Python ANTLR),和令牌名稱不存儲爲除模塊__dict__字符串,所以這是隻有獲得他們的方式。

我想,在C#中的令牌類型是枚舉,我相信枚舉可以打印爲字符串。但這只是一個猜測。

+0

賓果!`Console.WriteLine(ExpressionParser.tokenNames [tree.Type]);``int`存儲在`tree.Type`中,「dict」存儲在`___ Parser.tokenNames`中。 – mpen 2010-12-09 23:20:15

0

我是新來的ANTLR的,但它似乎ITree有可能與Parser(.NET中)沒有直接的義務。取而代之的是一個派生的接口IParseTree,返回從Parser(在Antlr4),它包含一些額外的方法,包括控制裝置:

string ToStringTree(Parser parser); 

它的整個節點樹轉換成文本表示。對於某些情況它很有用。

public static string GetNodeText(ITree t, Parser recog); 

這個方法並基本相同馬克羅伯特建議,但更多:如果你喜歡看一些具體的節點只是名字沒有它的孩子,然後在Trees類使用靜態方法一般而靈活的方式。

1

男孩,我花了太多的時間把我的頭撞在牆上試圖弄清楚這一點。馬克的回答給了我所需要的暗示,它看起來像下面將從TerminalNode在ANTLR的4.5獲得令牌名稱:

myLexer.getVocabulary.getSymbolicName(myTerminalNode.getSymbol.getType) 

,或者在C#:

myLexer.Vocabulary.GetSymbolicName(myTerminalNode.Symbol.Type) 

(貌似你實際上可以從解析器或詞法分析器獲取詞彙表。)

那些詞彙表方法似乎是在Antlr 4.5中獲得令牌的首選方式,並且tokenNames似乎已被棄用。

對於我認爲是非常基本的操作來說,它似乎不必要地複雜,所以也許有一種更簡單的方法。