使用 ANTLR 在 Java 源代码中查找变量 usage/reference?
Use ANTLR to find Variable usage/reference in Java source-code?
变量的使用基本上是变量声明后在同一范围内的每次出现,其中可能对其应用了一些操作。某些 IDE 甚至支持变量用法突出显示,例如 IntelliJ 和 Eclipse.
我想知道是否有办法使用 ANTLR 查找变量用法?我已经通过 [=] 生成了 Lexer、Parser 和 BaseListener classes 39=] Java8.g4 上的 ANTLR。我可以找到变量声明,但无法在给定的 Java 源代码中找到变量用法。我该怎么做?
示例:
int i; // Variable declaration
i++; // Variable usage
i = 2; // Variable usage
foo(i); // Variable 'i' usage
我可以使用 Listener class 捕获声明但不能捕获用法。我在这里解析 Java 源代码。
我假设您只考虑 local 变量。
你需要 scopes 和 resolving 才能做到这一点。
Scope 将代表 Java 的变量范围。它将保存有关在给定范围内声明了哪些变量的信息。您必须在进入 Java 作用域(块开始、方法等)时创建它,并在离开作用域时将其删除。您将保留一堆作用域来表示嵌套块/作用域(Java 不允许在嵌套作用域中隐藏局部变量,但您仍然需要跟踪变量何时超出作用域嵌套范围)。
然后您需要解析 您在解析输入中遇到的每个名称 - 确定名称是否指代变量(使用范围)。基本上,它指的是一个局部变量,只要它是名称的第一部分(在任何.
之前),后面没有(
并且匹配局部变量的名称。
解析器无法为您执行此操作,因为名称是否引用变量取决于可用变量:
private static class A {
B out = new B();
}
private static class B {
void println(String foo) {
System.out.println("ha");
}
}
public static void main(String[] args) {
{
A System = new A();
System.out.println("a");
}
System.out.println("b");
}
ha
b
如果您还考虑实例和静态字段而不仅仅是局部变量,解析部分会变得更加复杂,因为您需要考虑当前 class 中的所有 classes ]' 层次结构、它们的实例和静态字段、可见性等,以确定给定名称的变量是否存在和可见。
变量的使用基本上是变量声明后在同一范围内的每次出现,其中可能对其应用了一些操作。某些 IDE 甚至支持变量用法突出显示,例如 IntelliJ 和 Eclipse.
我想知道是否有办法使用 ANTLR 查找变量用法?我已经通过 [=] 生成了 Lexer、Parser 和 BaseListener classes 39=] Java8.g4 上的 ANTLR。我可以找到变量声明,但无法在给定的 Java 源代码中找到变量用法。我该怎么做?
示例:
int i; // Variable declaration
i++; // Variable usage
i = 2; // Variable usage
foo(i); // Variable 'i' usage
我可以使用 Listener class 捕获声明但不能捕获用法。我在这里解析 Java 源代码。
我假设您只考虑 local 变量。
你需要 scopes 和 resolving 才能做到这一点。
Scope 将代表 Java 的变量范围。它将保存有关在给定范围内声明了哪些变量的信息。您必须在进入 Java 作用域(块开始、方法等)时创建它,并在离开作用域时将其删除。您将保留一堆作用域来表示嵌套块/作用域(Java 不允许在嵌套作用域中隐藏局部变量,但您仍然需要跟踪变量何时超出作用域嵌套范围)。
然后您需要解析 您在解析输入中遇到的每个名称 - 确定名称是否指代变量(使用范围)。基本上,它指的是一个局部变量,只要它是名称的第一部分(在任何.
之前),后面没有(
并且匹配局部变量的名称。
解析器无法为您执行此操作,因为名称是否引用变量取决于可用变量:
private static class A {
B out = new B();
}
private static class B {
void println(String foo) {
System.out.println("ha");
}
}
public static void main(String[] args) {
{
A System = new A();
System.out.println("a");
}
System.out.println("b");
}
ha
b
如果您还考虑实例和静态字段而不仅仅是局部变量,解析部分会变得更加复杂,因为您需要考虑当前 class 中的所有 classes ]' 层次结构、它们的实例和静态字段、可见性等,以确定给定名称的变量是否存在和可见。