посетитель anltr4 не посещает узлы в дереве синтаксического анализа

#java #antlr

#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 вызовов внутри метода visit, он ничего не отображает. Кажется, он вообще не посещает узлы. С другой стороны, listener все работало просто отлично.

В чем проблема?

Ответ №1:

Проблема в том, что вы не переопределили visitor.visit(tree) метод, который в своей абстрактной реализации возвращает null .

Смысл шаблона посетителя (в отличие от слушателя) заключается в том, что вы решаете, какие узлы посещать. Вы можете посетить их все, посетить только те, которые вам нужны, или вообще ничего не посещать.

Итак, решение вашей проблемы будет либо:

  • Переопределите visit(ParseTree) метод в вашем HighLevelClassVisitor классе и обеспечьте надлежащую реализацию ( visitCompilationUnit() я думаю, вам также нужно будет реализовать).
  • или просто посещайте только те части дерева, которые вас действительно интересуют, т.е.:
     PackageDeclarationContext ctx = parser.packageDeclaration();
    HighLevelClassVisitor visitor = new HighLevelClassVisitor();
    System.out.println(visitor.visitPackageDeclaration(ctx).toString());