gpt4 book ai didi

java - 使用ANTLR对Java源文件进行静态分析

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:15:26 25 4
gpt4 key购买 nike

有没有人有使用ANTLR语法文件和Java源代码来分析Java源代码的完整实现(可能是github或googlecode)。例如,我希望能够简单地计算变量、方法等的数量。

同时使用最新版本的 ANTLR。

最佳答案

我想我会在午休时间尝试一下这个。这可能无法完全解决您的问题,但可以为您提供一个起点。该示例假定您在同一目录中执行所有操作。

  1. 下载 ANTLR source来自 GitHub。来自 ANTLR 站点的预编译“完整”JAR 包含一个已知错误。 GitHub 存储库有修复。

  2. 提取 ANTLR 压缩包。

    % tar xzf antlr-antlr3-release-3.4-150-g8312471.tar.gz
  3. 构建 ANTLR“完整”JAR。

    % cd antlr-antlr3-8312471
    % mvn -N install
    % mvn -Dmaven.test.skip=true
    % mvn -Dmaven.test.skip=true package assembly:assembly
    % cd -
  4. 下载 Java grammar .还有其他的,但我知道这个有效。

  5. 将语法编译为 Java 源代码。

    % mkdir com/habelitz/jsobjectizer/unmarshaller/antlrbridge/generated
    % mv *.g com/habelitz/jsobjectizer/unmarshaller/antlrbridge/generated
    % java -classpath antlr-antlr3-8312471/target/antlr-master-3.4.1-SNAPSHOT-completejar.jar org.antlr.Tool -o com/habelitz/jsobjectizer/unmarshaller/antlrbridge/generated Java.g
  6. 编译 Java 源代码。

    % javac -classpath antlr-antlr3-8312471/target/antlr-master-3.4.1-SNAPSHOT-completejar.jar com/habelitz/jsobjectizer/unmarshaller/antlrbridge/generated/*.java
  7. 添加以下源文件 Main.java。

    import java.io.IOException;
    import java.util.List;<br/>
    import org.antlr.runtime.*;
    import org.antlr.runtime.tree.*;<br/>
    import com.habelitz.jsobjectizer.unmarshaller.antlrbridge.generated.*;<br/>
    public class Main {
    public static void main(String... args) throws NoSuchFieldException, IllegalAccessException, IOException, RecognitionException {
    JavaLexer lexer = new JavaLexer(new ANTLRFileStream(args[1], "UTF-8"));
    JavaParser parser = new JavaParser(new CommonTokenStream(lexer));
    CommonTree tree = (CommonTree)(parser.javaSource().getTree());
    int type = ((Integer)(JavaParser.class.getDeclaredField(args[0]).get(null))).intValue();
    System.out.println(count(tree, type));
    }
    private static int count(CommonTree tree, int type) {
    int count = 0;
    List children = tree.getChildren();
    if (children != null) {
    for (Object child : children) {
    count += count((CommonTree)(child), type);
    }
    }
    return ((tree.getType() != type) ? count : count + 1);
    }
    }
  8. 编译。

    % javac -classpath .:antlr-antlr3-8312471/target/antlr-master-3.4.1-SNAPSHOT-completejar.jar Main.java
  9. 选择您要统计的 Java 源类型;例如,VAR_DECLARATORFUNCTION_METHOD_DECLVOID_METHOD_DECL

    % cat com/habelitz/jsobjectizer/unmarshaller/antlrbridge/generated/Java.tokens
  10. 在任何文件上运行,包括最近创建的 Main.java。

    % java -classpath .:antlr-antlr3-8312471/target/antlr-master-3.4.1-SNAPSHOT-completejar.jar Main VAR_DECLARATOR Main.java
    6

当然,这是不完美的。如果仔细观察,您可能会注意到增强的 for 语句的局部变量没有被计算在内。为此,您需要使用类型 FOR_EACH,而不是 VAR_DECLARATOR

您需要很好地理解 Java 源代码的元素,并且能够合理地猜测这些元素如何与该特定语法的定义相匹配。您也将无法进行引用计数。声明很简单,但例如,计算字段的使用需要引用解析。 p.C.f 是指 p 包内的类 C 的静态字段 f,还是指类 p 的静态字段 C 存储的对象的实例字段 f?基本解析器不会解析像 Java 这样复杂的语言的引用,因为一般情况下可能非常困难。如果你想要这种级别的控制,你需要使用编译器(或更接近它的东西)。 Eclipse 编译器是一个流行的选择。

我还应该提到,除了 ANTLR 之外,您还有其他选择。 JavaCC 是另一个解析器生成器。静态分析工具 PMD 使用 JavaCC 作为其解析器生成器,允许您编写可用于您指定的计数类型的自定义规则。

关于java - 使用ANTLR对Java源文件进行静态分析,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10523543/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com