посетитель anltr4 не посещает узлы в дереве разбора - PullRequest
1 голос
/ 17 апреля 2019

У меня есть простое приложение, которое использует 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 Ответ

3 голосов
/ 18 апреля 2019

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

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

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

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