antlr4 访问者不访问解析树中的节点
anltr4 visitor doesn't visit nodes in parse tree
我有一个使用 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());
我创建了一个简单的访问器,它应该 return 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;
}
}
但是当我执行应用程序时,它 returns null
作为 visit
方法的结果。当我在访问方法中放置一些 system.out
调用时,它什么也不显示。它似乎根本不访问节点。另一方面,listener
工作得很好。
有什么问题?
问题是您没有覆盖 visitor.visit(tree)
方法,在其抽象实现中,returns null。
访问者模式(与侦听器不同)的要点在于,您决定访问哪些节点。您可以访问所有这些,只访问您需要的那些,或者根本不访问任何东西。
因此,您的问题的解决方案可能是:
- 覆盖
HighLevelClassVisitor
class 中的 visit(ParseTree)
方法并提供正确的实现(我猜你还需要实现 visitCompilationUnit()
)。
- 或者,只访问树中您真正感兴趣的那些部分,即:
PackageDeclarationContext ctx = parser.packageDeclaration();
HighLevelClassVisitor visitor = new HighLevelClassVisitor();
System.out.println(visitor.visitPackageDeclaration(ctx).toString());
我有一个使用 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());
我创建了一个简单的访问器,它应该 return 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;
}
}
但是当我执行应用程序时,它 returns null
作为 visit
方法的结果。当我在访问方法中放置一些 system.out
调用时,它什么也不显示。它似乎根本不访问节点。另一方面,listener
工作得很好。
有什么问题?
问题是您没有覆盖 visitor.visit(tree)
方法,在其抽象实现中,returns null。
访问者模式(与侦听器不同)的要点在于,您决定访问哪些节点。您可以访问所有这些,只访问您需要的那些,或者根本不访问任何东西。
因此,您的问题的解决方案可能是:
- 覆盖
HighLevelClassVisitor
class 中的visit(ParseTree)
方法并提供正确的实现(我猜你还需要实现visitCompilationUnit()
)。 - 或者,只访问树中您真正感兴趣的那些部分,即:
PackageDeclarationContext ctx = parser.packageDeclaration();
HighLevelClassVisitor visitor = new HighLevelClassVisitor();
System.out.println(visitor.visitPackageDeclaration(ctx).toString());