anltr4访问者不访问解析树中的节点

时间:2019-04-17 17:14:10

标签: java antlr

我有一个使用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正常工作。

出什么问题了?

1 个答案:

答案 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());