我有一个使用ANTLR4处理Java
文件的简单应用程序。
InputStream stream = String.class.getResourceAsStream("/sample-function.java");
Java8Lexer lexer = new Java8Lexer(CharStreams.fromStream(stream));
CommonTokenStream tokens = new CommonTokenStream(lexer);
Java8Parser parser = new Java8Parser(tokens);
ParseTree tree = parser.compilationUnit();
HighLevelClassVisitor visitor = new HighLevelClassVisitor();
System.out.println(visitor.visit(tree).toString());
我创建了一个简单的访问者,该访问者在完成访问所有解析树节点后应返回string
。
public class HighLevelClassVisitor extends Java8BaseVisitor<StringBuilder> {
private StringBuilder sb = new StringBuilder();
@Override
public StringBuilder visitPackageDeclaration(PackageDeclarationContext ctx) {
sb.append("Package declaration: ").append(ctx.packageName().getText());
return sb;
}
@Override
public StringBuilder visitNormalClassDeclaration(NormalClassDeclarationContext ctx) {
sb.append("Class normal declaration: class ").append(ctx.Identifier().getText());
return sb;
}
@Override
public StringBuilder visitClassModifier(ClassModifierContext ctx) {
sb.append("Class modifier: ").append(ctx.getText());
return sb;
}
}
但是,当我执行该应用程序时,它返回null
作为visit
方法的结果。当我在访问方法中放置一些system.out
调用时,它什么也不显示。看来它根本不访问节点。另一方面,listener
正常工作。
出什么问题了?
答案 0 :(得分:3)
问题是您尚未覆盖visitor.visit(tree)
方法,该方法在其抽象实现中将返回null。
访问者模式(与侦听器不同)的重点在于,您决定要访问的节点。您可以访问所有这些对象,仅访问所需的对象,或者什么都不访问。
因此,解决您的问题的方法可能是:
visit(ParseTree)
类中覆盖HighLevelClassVisitor
方法并提供适当的实现(我想您还需要实现visitCompilationUnit()
)。 PackageDeclarationContext ctx = parser.packageDeclaration();
HighLevelClassVisitor visitor = new HighLevelClassVisitor();
System.out.println(visitor.visitPackageDeclaration(ctx).toString());