我有一个语法规则,
OR
: '|';
Run Code Online (Sandbox Code Playgroud)
但是当我用AST打印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);
}
Run Code Online (Sandbox Code Playgroud)
(感谢巴特)它显示了实际的|角色.有没有办法让我说"或"呢?
罗伯特启发了这个答案.
if (ExpressionParser.tokenNames[tree.Type] == tree.Text)
Console.WriteLine(tree.Text);
else
Console.WriteLine("{0} '{1}'", ExpressionParser.tokenNames[tree.Type], tree.Text);
Run Code Online (Sandbox Code Playgroud)
几个星期前我不得不这样做,但使用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
Run Code Online (Sandbox Code Playgroud)
令牌的编号没有明显的逻辑(至少,使用Python ANTLR),并且令牌名称除了在模块中之外不存储为字符串__dict__,因此这是获取它们的唯一方法.
我猜想在C#中,令牌类型在枚举中,我相信枚举可以打印成字符串.但这只是猜测.
男孩,我花了太多时间把头撞在墙上试图弄清楚这一点。Mark 的回答给了我所需的提示,看起来以下内容将从 Antlr 4.5 中的 TerminalNode 获取令牌名称:
myLexer.getVocabulary.getSymbolicName(myTerminalNode.getSymbol.getType)
Run Code Online (Sandbox Code Playgroud)
或者,在 C# 中:
myLexer.Vocabulary.GetSymbolicName(myTerminalNode.Symbol.Type)
Run Code Online (Sandbox Code Playgroud)
(看起来您实际上可以从解析器或词法分析器中获取词汇。)
在 Antlr 4.5 中,这些词汇方法似乎是获取标记的首选方式,而 tokenNames 似乎已被弃用。
对于我认为非常基本的操作来说,它确实看起来不必要地复杂,所以也许有一种更简单的方法。