最新想要学习分析java的AST,发现eclipse可以实现,但无奈网上大多都直接贴代码,没有告诉需要下什么jar包以及怎么导入,而eclipse并无自带AST的相关jar包,需要我们自己去找来下载。于是具体记录下,使用eclipse分析AST的具体流程,从依赖包的安装到具体代码实现。
一、安装 ASTView
打开Eclipse编辑器,点击Help→Eclipse Marketplace,搜索AST安装。
二、ASTView的使用
- 打开ASTView: Window > Show View > Other…, Java > AST View
- 点击工具栏中的 Show AST of active editor(F5)
- 双击 ASTNode 可以看到对应源文件中的代码位置
三、相关jar包下载
用ASTParser时,需要引入的包如下:
org.eclipse.core.contenttype.jar
org.eclipse.core.jobs.jar
org.eclipse.core.resources.jar
org.eclipse.core.runtime.jar
org.eclipse.equinox.common.jar
org.eclipse.equinox.preferences.jar
org.eclipse.jdt.core.jar
org.eclipse.osgi.jar
版本如下:
1.jar包下载
打开网址:https://mvnrepository.com/
以安装org.eclipse.jdt.core.jar为例子,打开网址搜索org.eclipse.jdt.core
记住自己下载的路径!!
2.eclipse导入jar包
eclipse新建个工程,不会建的看我之前的一篇博客:点此转跳
右键工程→new→folder,随便起个名字
然后把刚刚下的jar包放进新建的文件夹(lib)里头,但此时工程里的lib还是空的,因此右键lib→source→format,就可以把文件夹的文件导入工程里头。
选中导入的包,右键→Build Path→Add to Build Path,系统会自动生成Referenced Libraries文件夹,将jar包添加到构造路径。一个一个直至把所有的jar包都添加到构造路径。
大功告成!
四、代码实现
功能:输入一段包含java代码的文本,输出此段代码的AST。
此部分参考的是:【Eclipse AST】AST的获取与访问,然后进行详细的注释。
我的工程目录如下:
1.建个AST工具类,用于实现java源码→AST的转化。
Eclipse AST提供了ASTParser类用于解析源码,ASTParser有两种导入源代码的方式,一种是以Java Model的形式,另一种是以字符数组的形式,下面代码就是以字符数组形式导入。
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.jdt.core.dom.CompilationUnit;
public class JdtAstUtil {
/**
* get compilation unit of source code
* @param javaFilePath
* @return CompilationUnit
*/
//输入参数为需解析的Java源代码文件路径,返回值为该文件对应的CompilationUnit节点
public static CompilationUnit getCompilationUnit(String javaFilePath){
//判断输入文件是否存在和可用
byte[] input = null;
try {
BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(javaFilePath));
//将源码存储在字节数组
input = new byte[bufferedInputStream.available()];
bufferedInputStream.read(input);
bufferedInputStream.close();
} catch (FileNotFoundException e) {//异常检测
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
//创建ASTParser并将Java源文件解析成AST:
ASTParser astParser = ASTParser.newParser(AST.JLS3);
astParser.setSource(new String(input).toCharArray());
//设置要解析的类型,包含下面四种,可按需选择
//K_COMPILATION_UNIT:编译单元,即一个Java文件
//K_CLASS_BODY_DECLARATIONS:类的声明
//K_EXPRESSION:单个表达式
//K_STATEMENTS:语句块
astParser.setKind(ASTParser.K_COMPILATION_UNIT);
//获取代码的AST,实现AST解析
CompilationUnit result = (CompilationUnit) (astParser.createAST(null));
return result;
}
}
2.建个访问者类,实现AST节点访问
ASTView确定类、方法和属性的声明对应的AST节点分别是TypeDeclaration、MethodDeclaration和FieldDeclaration。依次获取即可。
import org.eclipse.jdt.core.dom.ASTVisitor;
import org.eclipse.jdt.core.dom.FieldDeclaration;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
public class DemoVisitor extends ASTVisitor {
//实现节点的打印,重写父类的一些方法实现节点打印
@Override
public boolean visit(FieldDeclaration node) {
for (Object obj: node.fragments()) {
VariableDeclarationFragment v = (VariableDeclarationFragment)obj;
System.out.println("Field:\t" + v.getName());
}
return true;
}
@Override
public boolean visit(MethodDeclaration node) {
System.out.println("Method:\t" + node.getName());
return true;
}
@Override
public boolean visit(TypeDeclaration node) {
System.out.println("Class:\t" + node.getName());
return true;
}
}
3.写个用于demo类,用来测试
public class ClassDemo {
private String text = "Hello World!", text2;
public void print(int value) {
System.out.println(value);
}
public void input(String value) {
text2 = value;
}
}
4.写个主类,实现demo类的AST解析
import org.eclipse.jdt.core.dom.CompilationUnit;
public class Main {
public static void main(String[] args) {
//源码与AST转换
CompilationUnit comp = JdtAstUtil.getCompilationUnit("你写的demo类的绝对路径\\ClassDemo.java");
//实例化访问者类,配合前面写的工具类访问节点
DemoVisitor visitor = new DemoVisitor();
comp.accept(visitor);
}
}
输出如下:
Class: ClassDemo
Field: text
Field: text2
Method: print
Method: input
参考文献
【Eclipse AST】AST的获取与访问:https://blog.csdn.net/lovelion/article/details/19050155/