使用antlr4解析java代码时导航到不属于上下文的标记
我正在使用Antlr4.2解析Java源文件 我的目标是在类中找到具有特定注释的方法 我面临的问题是,语法没有将使用antlr4解析java代码时导航到不属于上下文的标记,java,antlr4,Java,Antlr4,我正在使用Antlr4.2解析Java源文件 我的目标是在类中找到具有特定注释的方法 我面临的问题是,语法没有将注释规则作为方法声明规则的一部分(这很有意义),这意味着当我重写JavaBaseListener的enterMethodDeclaration时,上下文对象无法直接使用它: @Override public void enterMethodDeclaration(@NotNull JavaParser.MethodDeclarationContext ctx) { // How
注释
规则作为方法声明
规则的一部分(这很有意义),这意味着当我重写JavaBaseListener的enterMethodDeclaration
时,上下文对象无法直接使用它:
@Override
public void enterMethodDeclaration(@NotNull JavaParser.MethodDeclarationContext ctx) {
// How do I access the annotation on the method in 'ctx'?
}
到目前为止,我唯一的想法是获取令牌流,并尝试从方法声明上下文的位置向后遍历它。问题是它非常麻烦(方法上的注释可能在修饰符之前,如果修饰符确实存在,则在修饰符之后),我觉得它缺少了侦听器/访问者方法的要点
是否有一个干净的方法来获得一个方法的注释?
,而不是试图遍历解析树,考虑下去。您可以从classBodyDeclaration
产品开始,检查是否可以进入memberDeclaration
并从那里进入methodDeclaration
。如果是这样的话,你就知道你目前正在使用一种方法。然后只需在classBodyDeclaration
中的修饰符列表上迭代即可找到注释
快速演示:
public class Main {
public static void main(String[] args) throws Exception {
String input = "@Annotation(\"class\")\n" +
"class Mu {\n" +
"\n" +
" @Annotation(\"field\")\n" +
" int x;\n" +
" \n" +
" @Annotation(\"method\")\n" +
" void withAnnotation(){}\n" +
" \n" +
" void withoutAnnotation(){}\n" +
"}";
JavaLexer lexer = new JavaLexer(new ANTLRInputStream(input));
JavaParser parser = new JavaParser(new CommonTokenStream(lexer));
// classBodyDeclaration
// : ...
// | modifier* memberDeclaration
// ;
//
// memberDeclaration
// : methodDeclaration
// | ...
// ;
//
// methodDeclaration
// : (type|'void') Identifier formalParameters ...
// ;
//
// modifier
// : classOrInterfaceModifier
// | ...
// ;
//
// classOrInterfaceModifier
// : annotation
// | ...
// ;
ParseTreeWalker.DEFAULT.walk(new JavaBaseListener(){
@Override
public void enterClassBodyDeclaration(@NotNull JavaParser.ClassBodyDeclarationContext ctx) {
if (!(ctx.memberDeclaration() != null && ctx.memberDeclaration().methodDeclaration() != null)) {
// No method declaration.
return;
}
String methodName = ctx.memberDeclaration().methodDeclaration().Identifier().getText();
for (JavaParser.ModifierContext mctx : ctx.modifier()) {
if (mctx.classOrInterfaceModifier() != null && mctx.classOrInterfaceModifier().annotation() != null) {
System.out.println(methodName + " -> " + mctx.classOrInterfaceModifier().annotation().getText());
}
}
}
}, parser.compilationUnit());
}
}
其中打印:
withAnnotation -> @Annotation("method")
withAnnotation->@Annotation(“方法”)正是我想要的。需要一段时间来适应这项技术。谢谢