有人知道在C#中使用ANTLR生成的AST的教程吗?我能找到的最接近的是this,但是它并不是很有帮助。
我的目标是遍历根据我正在使用的领域特定语言生成的树,并使用这些树输出生成的C#代码。
基于Java的教程也将有所帮助-任何提供了如何遍历ANTLR AST的清晰示例的内容。
通过修改Manuel Abadia文章结尾的示例,我设法弄清了这一点。
这是我的版本,我刚好用它来将解析的代码转换为C#。这些步骤是:
CommonTree
要获取节点的文字文本,请使用node.Text。要获取节点的令牌名称,请使用node.Token.Text。
node.Text
node.Token.Text
请注意,node.Token.Text如果它是一个虚构的令牌,没有相应的字符串,则只会为您提供令牌的实际名称。如果它是真实的令牌,node.Token.Text则将返回其字符串。
例如,如果语法中包含以下内容:
tokens { PROGRAM, FUNCDEC } EQUALS : '=='; ASSIGN : '=';
然后你会得到"PROGRAM","FUNCDEC","==",并"="从相应的访问node.Token.Text。
"PROGRAM"
"FUNCDEC"
"=="
"="
您可以在下面查看我的示例的一部分,也可以浏览完整版本。
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 += "\r\n\r\n// GLOBALS\r\n"; PrintChildren(ast); break; case "GLOBAL": body += "public static "; PrintChildren(ast); body += ";\r\n"; break; .... } }