АНТЛР: Получить имя токена? - PullRequest
10 голосов
/ 10 декабря 2010

У меня есть правило грамматики,

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);
}

(Спасибо Барт ), он отображаетфактический | символ.Есть ли способ заставить его сказать «ИЛИ» вместо этого?

Ответы [ 4 ]

9 голосов
/ 10 декабря 2010

Роберт вдохновил этот ответ.

if (ExpressionParser.tokenNames[tree.Type] == tree.Text)
    Console.WriteLine(tree.Text);
else
    Console.WriteLine("{0} '{1}'", ExpressionParser.tokenNames[tree.Type], tree.Text);
7 голосов
/ 10 декабря 2010

Я должен был сделать это пару недель назад, но с 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 # типы токенов находятся в перечислении, и я считаю, что перечисления могут быть напечатаны как строки.Но это только предположение.

1 голос
/ 21 августа 2015

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

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

или в C #:

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

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

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

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

0 голосов
/ 16 июня 2015

Я новичок в Antlr, но, похоже, ITree не имеет прямого обязательства быть связанным с Parser (в .NET).Вместо этого есть производный интерфейс IParseTree, возвращаемый из Parser (в Antlr4), и он содержит несколько дополнительных методов, включая переопределение:

string ToStringTree(Parser parser);

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

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

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

...