问题
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.
回答1:
"{[]}" 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.
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); }.
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.
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.
来源:https://stackoverflow.com/questions/62666037/antlr-visitor-class-is-returning-null-for-parse-tree-in-c-sharp