使用ANTLR在Java源代码中查找变量用法/引用?

时间:2017-06-08 05:50:29

标签: java parsing antlr abstract-syntax-tree

变量用法基本上是变量在相同范围内声明后的每次出现,其中可能会对其应用某些操作。某些IDE甚至支持变量用法突出显示,例如 IntelliJ Eclipse

我想知道是否有办法使用ANTLR查找变量用法?我已经通过在 Java8.g4 上运行ANTLR生成了 Lexer Parser BaseListener 类。我可以找到变量声明,但无法在给定的Java源代码中找到变量用法。我怎么能这样做?

示例:

int i;    // Variable declaration
i++;      // Variable usage
i = 2;    // Variable usage
foo(i);   // Variable 'i' usage

我可以使用 Listener 类捕获声明但不能使用。我在这里解析Java源代码。

1 个答案:

答案 0 :(得分:0)

我假设您只考虑本地变量。

您需要范围解析才能执行此操作。

范围将代表Java的变量范围。它将保存有关在给定范围内声明哪些变量的信息。当您输入Java范围(块的开始,方法,...)时,您必须创建它,并在离开范围时将其删除。您将保留一堆作用域来表示嵌套的块/作用域(Java不允许在嵌套作用域中隐藏局部变量,但您仍需要跟踪变量何时超出嵌套作用域末尾的作用域)。

然后你需要解析你在解析输入中遇到的每个名字 - 确定名称是否引用变量(使用范围)。基本上,它引用局部变量,只要它是名称的第一部分(在任何.之前),后面跟(并且匹配局部变量的名称。

Parser无法为您执行此操作,因为名称是否引用变量取决于可用变量:

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");
}
  

公顷
  B'/ P>

如果你也在考虑实例和静态字段而不仅仅是局部变量,解析部分会变得复杂得多,因为你需要考虑当前类层次结构中的所有类,它们的实例和静态字段,可见性确定给定名称的变量是否存在且可见。