【问题标题】:Use ANTLR to find Variable usage/reference in Java source-code?使用 ANTLR 在 Java 源代码中查找变量使用/引用?
【发布时间】:2017-06-08 05:50:28
【问题描述】:

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

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

例子:

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

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

【问题讨论】:

标签: java parsing antlr abstract-syntax-tree


【解决方案1】:

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

您需要 scopesresolving 来执行此操作。

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

哈哈
b


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

【讨论】:

  • 实际上,使用 ANTLR 的 Listener 类,我能够捕获所有代表 Java8.g4 中指定的变量的 expressionnames。
  • 它是否适用于此答案中的代码,即它仅将System"a" 标识为变量引用?
  • 它正确显示'System'是该行的一个变量。我不确定"a" as variable reference 是什么意思。
  • 我的意思是它只将System 标识为该行上的变量(第二次出现),并在其余两种情况下将其正确标识为类引用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-09
  • 1970-01-01
  • 2013-10-28
  • 2013-08-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多