如何使用 ANTLR4 获取 class 字段名称?

How to get class field name using ANTLR4?

我有 java9 源代码,我需要使用 antlr4 提取一些 classes 的字段。这是我的听众:

private static class FieldListener extends Java9BaseListener {

        @Override
        public void enterFieldDeclaration(Java9Parser.FieldDeclarationContext ctx) {
            for (ParseTree subTree : ctx.children) {
                System.out.println(subTree.getText());
            }
            String fieldName = ??????;
        }

    }

这是代码

        //Now, let's do some testing. First, we construct the lexer:
        Java9Lexer java9Lexer = new  Java9Lexer(CharStreams.fromString(classContent));

        //Then, we instantiate the parser:
        CommonTokenStream tokens = new CommonTokenStream(java9Lexer);
        Java9Parser parser = new Java9Parser(tokens);
        ParseTree tree = parser.compilationUnit();

        //And then, the walker and the listener:
        ParseTreeWalker walker = new ParseTreeWalker();
        walker.walk(new FieldListener(), tree);

但是,我只能迭代所有字段标记,但无法获取特定标记 - class fieldName。谁能说说怎么弄?

这里没有匹配项目符号。静态语义分析并不容易,因为您必须 运行 围绕一棵树。但这是直截了当的。您将不得不通过树遍历从 variableDeclaratorList 中提取字段的名称。如果您为某些输入打印出解析树,您可以看到 variableDeclaratorList 包含一个 variableDeclarator 列表,每个 variableDeclarator 包含一个 variableDeclaratorId,每个 variableDeclaratorId 包含一个 identifier 和可选的 dims,以及每个 identifier 标记的子树 JavaLetter 以及更多 JavaLetterOrDigit。你应该如何计算解析树的属性?这取决于你。通常,人们使用这个 Antlr 侦听器框架来计算综合属性。您可以定义从节点到包含属性的数据结构的映射,这样当您想要树中较低节点的属性时,您可以进行查找(在这种情况下,可能会生成 variableDeclaratorList?)。您可以使用该子节点的访问器函数访问特定节点,这样您就不必计算直接后代的属性。查看生成的解析器代码。您可以看到可用的内容,例如 FieldDeclarationContext.variableDeclaratorList()。或者,如果您愿意,可以调用一个函数来派生此特定 variableDeclaratorList 的属性,而不是使用 Antlr 侦听器框架。 Antlr Listener 没有短路,所以请注意,如果您编写自己的函数来遍历 variableDeclaratorList,您可能不想使用侦听器 ParseTreeWalker.walk() 而是使用 ParseTreeVisitor.visit().