ANTLR 访问者类在 C# 中为解析树返回 null [英] ANTLR Visitor Class is returning null for Parse tree in C#

查看:33
本文介绍了ANTLR 访问者类在 C# 中为解析树返回 null的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 ANTLR Java 语法上的访问者模式构建 AST (Java 语法)在 C#(.Net Core 3.1)中.我已经为语法创建了 IJavaParserVisitorJavaParserbaseVisitorJavaLexerJavaParser 文件,并为 java 源文件创建了解析树.但是当我尝试使用 JavaParserBaseVisitor.Visit() 创建 AST 时,结果为 null.

I am trying to build an AST using the visitor pattern on ANTLR Java Grammar (Java Grammar) in C# (.Net Core 3.1). I have created IJavaParserVisitor, JavaParserbaseVisitor, JavaLexer, and JavaParser file for grammar and created parse tree for java source file. But when I am trying to create AST using JavaParserBaseVisitor.Visit() I am getting null as a result.

 AntlrFileStream stream = new AntlrFileStream(file);
 ITokenSource lexer = new JavaLexer(stream);
 ITokenStream tokens = new CommonTokenStream(lexer);
 JavaParser parser = new JavaParser(tokens);
 parser.BuildParseTree = true;
 IParseTree tree = parser.compilationUnit();
 var result = tree.ToStringTree(parser);
 JavaParserBaseVisitor<JavaParser> visitor = new 
 JavaParserBaseVisitor<JavaParser>();
 var ast= visitor.Visit(tree); -- **Its always NULL**

我不知道我在这里缺少什么.

I don't what exactly I am missing here.

推荐答案

"{[]}"很好.这就是ToString()"解析树中节点的表示.如果您不确定节点是什么,请尝试查看tree.GetText()";和tree.GetType()"在调试器中.

"{[]}" is fine. That's the "ToString()" representation of a node in the parse tree. If you aren't sure what a node is, trying looking at "tree.GetText()" and "tree.GetType()" in the debugger.

但是,您的访问者代码看起来不正确.您需要类似public class MyVisitor : JavaParserBaseVisitor<AST>"的东西.{...}",其中 AST 是一个类或接口,用于表示抽象语法树中的节点.这就是您从每个访问者返回的内容,而不是 JavaParser 或 IParseTree.在您的访问者类中,您将需要覆盖您想要的所有内容的实现,计算并返回对应于该解析树节点的 AST(或只是一个特定子节点的 AST).在每个访问者方法中,您需要为每个孩子调用访问者.例如, VisitForInit(...) { var r = VisitExpressionList(context.expressionList());...;返回新的 ForAST(r);}.

But, your visitor code doesn't look right. You need something like "public class MyVisitor : JavaParserBaseVisitor<AST> {...}", where AST is a class or interface used to represent a node in the abstract syntax tree. That's what you're returning from each visitor, not a JavaParser, or an IParseTree. In your visitor class, you're going to need to override the implementations for everything you want, computing and returning the AST corresponding to that parse tree node (or just the AST for one particular child). In each visitor method, you will need to call the visitor for each child. For example, VisitForInit(...) { var r = VisitExpressionList(context.expressionList()); ... ; return new ForAST(r); }.

请注意,有些人创建了许多 AST 节点类,它们是从 AST 子类化的,它们代表不同的 AST 节点类型.例如,您可能需要一个用于语句,另一个用于变量声明等.如果您打算为所有 Java 创建一个完整的 AST,那么您有很多工作要做.或者,您可以创建一个通用 AST 节点类,其中包含您为解析树节点创建的子 AST 列表和一个用于区分 AST 节点类型的枚举.

Note, some people create a number of AST node classes subclassed from AST which represent different AST node types. You might, for example, need one for statements, another for variable decls, etc. You have a lot of work ahead of you if you intend to create a complete AST for all of Java. Alternatively, you could create a general AST node class, which has a list of children ASTs that you created for the parse tree node and an enum to distinguish the type of the AST node.

如果您想查看有关其工作原理的真实示例,请查看 为 XPath 引擎构建 XPath AST 表达式的访问者 我刚刚移植到 C# 并扩展到 XPath 3.1.这为表达式构造了一个 AST(这里只是一个对象).

If you like to see a real-world example of how this works, check out the visitor for constructing a XPath AST expression for an XPath engine I just ported to C# and extending to XPath 3.1. This constructs an AST (here just an object) for an expression.

这篇关于ANTLR 访问者类在 C# 中为解析树返回 null的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆