通过修改Manuel
Abadia文章结尾的示例,我设法弄清了这一点。
这是我的版本,我刚好用它来将解析的代码转换为C#。这些步骤是:
- 使用您的输入实例化ANTLRStringStream或子类(它可以是文件或字符串)。
- 实例化生成的词法分析器,并传入该字符串流。
- 使用词法分析器实例化令牌流。
- 使用该令牌流实例化解析器。
- 从解析器获取顶级值,然后将其转换为
CommonTree
。 - 遍历树:
要获取节点的文字文本,请使用
node.Text。要获取节点的令牌名称,请使用
node.Token.Text。
请注意,
node.Token.Text如果它是一个虚构的令牌,没有相应的字符串,则只会为您提供令牌的实际名称。如果它是真实的令牌,
node.Token.Text则将返回其字符串。
例如,如果语法中包含以下内容:
tokens { PROGRAM, FUNCDEC }EQUALS : '==';ASSIGN : '=';然后你会得到
"PROGRAM",
"FUNCDEC",
"==",并
"="从相应的访问
node.Token.Text。
您可以在下面查看我的示例的一部分,也可以浏览完整版本。
public static string Convert(string input){ ANTLRStringStream sStream = new ANTLRStringStream(input); MyGrammarLexer lexer = new MyGrammarLexer(sStream); CommonTokenStream tStream = new CommonTokenStream(lexer); MyGrammarParser parser = new MyGrammarParser (tStream); MyGrammarParser.program_return parserResult = parser.program(); CommonTree ast = (CommonTree)parserResult.Tree; Print(ast); string output = header + body + footer; return output;}public static void PrintChildren(CT ast){ PrintChildren(ast, " ", true);}public static void PrintChildren(CT ast, string delim, bool final){ if (ast.Children == null) { return; } int num = ast.Children.Count; for (int i = 0; i < num; ++i) { CT d = (CT)(ast.Children[i]); Print(d); if (final || i < num - 1) { body += delim; } }}public static void Print(CommonTree ast){ switch (ast.Token.Text) { case "PROGRAM": //body += header; PrintChildren(ast); //body += footer; break; case "GLOBALS": body += "rnrn// GLOBALSrn"; PrintChildren(ast); break; case "GLOBAL": body += "public static "; PrintChildren(ast); body += ";rn"; break; .... }}


