#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());