2010-12-09 1 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) отображает фактическое | характер. Есть ли способ заставить меня сказать «ИЛИ»?

ответ

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

Я должен был сделать это пару недель назад, но с ANTLR Python. Это не поможет вам, но может помочь кому-то еще найти ответ.

С ANTLR Python типы токенов являются целыми числами. Текст маркера включен в объект токена. Вот решение, которое я использовал:

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

Bingo!`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); 

Он преобразует поддерево всего узла в текстовое представление. В некоторых случаях это полезно. Если вы хотели бы видеть только название какого-либо конкретного узла без его детей, а затем использовать статический метод в классе Trees:

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

Этот способ в основном такой же, как Марка и Роберт предложил, но в более общий и гибкий способ.

1

Мальчик, я потратил слишком много времени, ударяя головой о стену, пытаясь понять это. Ответ Марк дал мне подсказку мне нужно, и это выглядит следующим образом получит имя лексемы из TerminalNode в Antlr 4.5:

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

или, в C#:

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

(Похоже, вы может фактически получить словарь либо из анализатора, либо из лексера.)

Эти словарные методы, по-видимому, являются предпочтительным способом получить маркеры в Antlr 4.5, а tokenNames, как представляется, устарели.

Это кажется излишне сложным для того, что я считаю довольно простой операцией, поэтому, возможно, есть более простой способ.

 Смежные вопросы

  • Нет связанных вопросов^_^