C# ANTLR:获取令牌名称?
我有一条语法规则C# ANTLR:获取令牌名称?,c#,antlr,C#,Antlr,我有一条语法规则 OR : '|'; 但是当我用 public static void Preorder(ITree tree, int depth) { if (tree == null) { return; } for (int i = 0; i < depth; i++) { Console.Write(" "); } Console.WriteLine(tree); f
OR
: '|';
但是当我用
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);
}
publicstaticvoidpreorder(itreetree,int-depth)
{
if(tree==null)
{
返回;
}
for(int i=0;i 对于(inti=0;i几周前我不得不这样做,但是使用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中是这样),并且令牌名称不会存储为字符串,除非存储在模块\uuuuu dict\uuuu
中,因此这是获取它们的唯一方法
我猜在C#中,令牌类型在枚举中,我相信枚举可以打印为字符串。但这只是猜测。给出了这个答案
if (ExpressionParser.tokenNames[tree.Type] == tree.Text)
Console.WriteLine(tree.Text);
else
Console.WriteLine("{0} '{1}'", ExpressionParser.tokenNames[tree.Type], tree.Text);
我是Antlr新手,但似乎ITree
没有直接义务与解析器
(在.NET中)相关。相反,它有一个派生接口IParseTree
,从解析器
(在Antlr4中)返回,并且它包含一些附加方法,包括覆盖:
string ToStringTree(Parser parser);
它将整个节点子树转换为文本表示。在某些情况下,它很有用。如果您只想看到某个具体节点的名称而不想看到它的子节点,请在类树中使用static方法
:
public static string GetNodeText(ITree t, Parser recog);
这个方法与Mark和Robert建议的基本相同,但更为通用和灵活。天哪,我花了太多时间把头撞在墙上试图弄明白这一点。Mark的回答给了我需要的提示,看起来下面将从Antlr 4.5中的终端节点获取令牌名称:
myLexer.getVocabulary.getSymbolicName(myTerminalNode.getSymbol.getType)
或者,在C#中:
(看起来您实际上可以从解析器或词法分析器中获取词汇表。)
在Antlr 4.5中,这些词汇表方法似乎是获取标记的首选方法,而标记名似乎已被弃用
对于我认为是一个非常基本的操作来说,它似乎不必要地复杂,所以可能有一个更简单的方法。Bingo!Console.WriteLine(ExpressionParser.tokenNames[tree.Type]);
int
存储在tree.Type
和“dict”中存储在\uuu解析器中。标记名。似乎标记名数组已被弃用(至少在Antlr 4.5中是这样)。请改用基于词汇表的方法-请参阅下面的答案。或者在JS:this.lexer.symbolicNames[node.type]中,谢谢!
myLexer.Vocabulary.GetSymbolicName(myTerminalNode.Symbol.Type)