我有java9源代码,我需要使用antlr4提取某些类的字段。这是我的听众:
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);
但是,我只能迭代所有字段标记,而不能获取特定的标记-类fieldName。谁能说出如何获得它?
这里没有匹配的项目符号。静态语义分析并不容易,因为您必须围绕一棵树运行。但这很简单。您将必须通过variableDeclaratorList的树步提取字段的名称。如果为某些输入打印出分析树,则可以看到variableDeclaratorList包含一个variableDeclarator列表,每个variableDeclarator包含一个variableDeclaratorId,每个variableDeclaratorId] >包含带有可选dims的identifier,并且每个identifier都是令牌JavaLetter和更多JavaLetterOrDigit的子树。您应该如何计算解析树的属性?随你(由你决定。通常,人们使用此Antlr侦听器框架来计算综合属性。您可以定义从节点到包含属性的数据结构的映射,因此,当您希望树中节点的属性较低时,可以进行查找(在这种情况下,可能会产生< [variableDeclaratorList?)。您可以使用该子节点的访问器功能来访问特定节点,因此不必从直系后代中计算属性。查看生成的解析器代码。您可以看到可用的内容,例如FieldDeclarationContext.variableDeclaratorList()。或者,如果愿意,可以调用一个函数来派生此特定variableDeclaratorList的属性,而不是使用Antlr侦听器框架。Antlr Listener并没有短路,因此请注意,如果您编写自己的函数来滑动variableDeclaratorList,则可能不想使用监听器ParseTreeWalker.walk()而是使用ParseTreeVisitor.visit()。