java - 使用 ANTLR4 解析 java 文件时,如何保存方法名称和在该方法中调用的所有方法的名称?
问题描述
我正在开发一个程序,该程序使用来自 ANTLRs github 的 Java9 词法分析器和语法来解析 Java 文件。解析文件时,我想将每个方法名称以及在该方法中调用的所有方法的名称保存在HashMap<String, Set<String>>
.
我使用侦听器模式,其中我使用方法exitMethodDeclaration来获取方法名称和exitMethodInvocation来获取方法调用。问题是这两种方法是在解析树的不同节点上调用的,因此它们将不同的上下文作为参数。因此,据我所知,我无法调用该方法来获取exitMethodDeclaration内部的调用。我尝试构建自己的递归,这样我就可以通过将 methodDeclarationContext 作为参数传递给exitMethodInvocation来解决类型问题。不过,这将非常复杂,我想使用 ANTLRs 功能。
使用下面的代码,每个方法的 hashSet 包含整个文件的所有方法调用,而不仅仅是特定方法。
private HashMap<String, HashSet<String>> methodCalls = new HashMap<>();
private HashSet<String> methodCallNames = new HashSet<>();
public void exitMethodDeclaration(Java9Parser.MethodDeclarationContext ctx) {
String methodName = ctx.methodHeader().methodDeclarator().identifier().getText();
methodCalls.put(methodName, methodCallNames);
}
public void exitMethodInvocation(Java9Parser.MethodInvocationContext ctx) {
try {
String m = ctx.methodName().identifier().getText();
methodCallNames.add(m);
} catch (Exception e) {
}
}
任何关于如何在同一方法中收集不同上下文类型的节点、访问侦听器/访问者方法中的子树或其他想法的想法都非常受欢迎!
解决方案
您可以创建一个 ArrayLists 堆栈。
每次,您enterMethodDeclaration
将一个新的 Empty ArrayList 推送到您的 Stack。
每次您enterMethodInvocation
(或者exit...
如果您愿意),您可以将 methodName 添加到您在 stack.peek() 上的 ArrayList 中。
每当你exitMethodDeclartation
stack.pop() 你 ArrayList 时,它都会列出你在该方法调用中直接遇到的所有方法名称。而且,方法名称就在 Context 参数中exitMethodDeclaration
推荐阅读
- ios - 访问 Apple AirTag 数据的 Apple Developer API 是什么?
- javascript - Reactjs 使用 useReducer 更新对象数组中的嵌套数组
- python - 如何在 Pandas uisng for 循环中过滤 DataFrame 中的行?
- python - 禅比;自定义字段未更新
- reactjs - 升级到 Visual Studio 2019 16.10.0 后 React 应用的“加载资源失败:net::ERR_HTTP2_PROTOCOL_ERROR”
- r - `summary_rows` 之后的跨列摘要与 gt
- javascript - 根据另一个 [TS/JS] 过滤一组对象
- javascript - React defaultChecked 无线电输入(使用 react-hook-form)
- java - 使用 JSTL 时出现 JasperException
- laravel - 无法从 Homestead 上的 Laravel 6 连接到邮件服务器