有没有一个完整的实现(可能是github或googlecode),用于使用ANTLR语法文件和Java源代码分析Java源代码。例如,我想简单地能够计算变量、方法等数量。
同时使用最新版本的ANTLR。
有没有一个完整的实现(可能是github或googlecode),用于使用ANTLR语法文件和Java源代码分析Java源代码。例如,我想简单地能够计算变量、方法等数量。
同时使用最新版本的ANTLR。
我想在午餐时间试着解决这个问题。这可能并不能完全解决你的问题,但可以帮助你入门。示例假设你把所有东西都放在同一个目录下。
从GitHub下载ANTLR源代码。来自ANTLR官网的预编译“complete”JAR文件存在已知的bug。GitHub上的存储库有修复。
解压ANTLR tarball。
% tar xzf antlr-antlr3-release-3.4-150-g8312471.tar.gz
构建 ANTLR "complete" JAR。
% cd antlr-antlr3-8312471
% mvn -N install
% mvn -Dmaven.test.skip=true
% mvn -Dmaven.test.skip=true package assembly:assembly
% cd -
下载一个Java语法文件。虽然有其他的选择,但我知道这个是有效的。
将语法文件编译成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
编译Java源代码。
% javac -classpath antlr-antlr3-8312471/target/antlr-master-3.4.1-SNAPSHOT-completejar.jar com/habelitz/jsobjectizer/unmarshaller/antlrbridge/generated/*.java
将以下源文件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);
}
}
编译。
% javac -classpath .:antlr-antlr3-8312471/target/antlr-master-3.4.1-SNAPSHOT-completejar.jar Main.java
选择您想要计数的Java源代码类型;例如,VAR_DECLARATOR
,FUNCTION_METHOD_DECL
或VOID_METHOD_DECL
。
% cat com/habelitz/jsobjectizer/unmarshaller/antlrbridge/generated/Java.tokens
运行任何文件,包括最近创建的 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
。p.C.f
是指包p
内的一个类C
的静态字段f
,还是指由类p
的静态字段存储的对象中的实例字段f
?基本解析器不能解析像Java这样复杂的语言的引用,因为一般情况下可能非常困难。如果您想要这种级别的控制,您需要使用编译器(或更接近编译器的东西)。Eclipse编译器是一个流行的选择。