Java AST( Tree)
最近做项目用到了Rust作为后台,前端通过自定义的DSL,在后台通过rahi生成对应的可执行代码,大概看了下,主要是基于Rust AST解析字符串并生成Rust代码。
于是也看了下java中如何一样如何执行DSQL语句,今天介绍Java AST的概念、应用和操作,并通过示例和图解等形式ast树,更直观地理解和掌握这一技术。
Java AST概述
Java AST是一种树形的数据结构,它表示了Java源代码的抽象语法。在Java编译器中,源代码被解析成一个AST,然后编译器会对这个AST进行各种操作,如检查语法错误、生成字节码等。Java AST包含了源代码的结构化信息,可以用于很多编程任务,如代码分析、重构、生成等。
Java AST的应用
Java AST广泛应用于编程任务的各个环节,如下:
Java AST操作示例
以下是一个简单的Java AST操作示例,展示了如何通过Java AST遍历和修改代码:
public class SourceCodeParser {
public static void main(String[] args) {
// 创建一个源代码字符串
String sourceCode = " public class Adder {" +
" public int add(double a, double b) {" +
" double sum = a + b;" +
" return sum.intValue();" +
" }" +
" }";
// 创建一个 AST 构建器
ASTParser parser = ASTParser.newParser(AST.JLS8);
parser.setSource(sourceCode.toCharArray());
parser.setKind(ASTParser.K_COMPILATION_UNIT);
// 解析源代码并创建 AST
CompilationUnit cu = (CompilationUnit) parser.createAST(null);
AST ast = cu.getAST();
cu.accept(new ASTVisitor() {
@Override
public boolean visit(MethodDeclaration node) {
node.setName(ast.newSimpleName("plus"));
// 获取方法体并更改其内容
if (node.getBody() != null) {
List statements = node.getBody().statements();
for (Object statement : statements) {
System.out.println( statement.getClass() );
}
}
return true; // 继续遍历其他节点(如果有)
}
});
System.out.println( cu.toString() );
}
}
上面的例子通过解析源代码为AST并修改方法名称,实现步骤如下:
将源代码解析成Java AST。
遍历Java AST,找到需要处理方法的节点。
重新设置方法名称。
将修改后的Java AST转换回源代码。
图解Java AST
以下是一个简单的图解示例,展示了Java AST的基本结构:
┌─────────────┐
│ Java AST │
└─────────────┘
|
v
┌─────────────┐
│ Class │
└─────────────┘
|
v
┌─────────────┐
│ Method │
└─────────────┘
|
v
┌─────────────┐
│ Statement │
└─────────────┘
|
v
┌─────────────┐
│ Expression│
└─────────────┘
|
v
┌─────────────┐
│ Literal │
└─────────────┘
在这个图解中,Java AST被表示为一棵树,根节点是Java AST,它包含了整个Java程序的语法结构。从这个根节点出发,我们可以看到它包含了一个Class节点,表示Java程序中的一个类。这个Class节点下又包含了一个节点,表示这个类中的一个方法。节点下是一个节点,表示方法中的一个语句。节点下是一个节点,表示语句中的一个表达式。最后,节点下是一个节点,表示表达式中的一个字面量(例如字符串、数字等)。通过这样的图解,读者可以直观地理解Java AST的结构,以及如何在不同的节点之间进行操作。
执行
通过上面的方式可以对传入的字符串进行语法解析以及修改,然后通过执行引擎执行代码。
public class Runner{
public Object execute(String sourceCode, String methodName, Object[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
GroovyClassLoader loader = new GroovyClassLoader();
Class scriptClass = loader.parseClass(sourceCode);
GroovyObject scriptInstance = (GroovyObject) scriptClass.getDeclaredConstructor().newInstance();
return scriptInstance.invokeMethod(methodName, args);
}
public static void main(String[] args) throws Exception {
String java = " public class Adder {" +
" public int add(double a, double b) {" +
" double sum = a + b;" +
" return sum.intValue();" +
" }" +
" }";
Runner executor = new Runner();
Object result = executor.execute(java ,"add", new Object[]{1, 2});
System.out.println("Groovy result=" + result);
}
}
总结:
本文深入浅出地介绍了Java AST的概念、应用和操作,并通过示例和图解等形式,使读者更直观地理解和掌握这一技术。Java AST在代码分析、重构、生成等方面有着广泛的应用,是编程任务中不可或缺的一部分。
写在最后
时隔2个月,某鱼群再次限时开放了 。
Java技术指北读者交流群,(摸鱼,白嫖技术课程ast树,最新时事,GPT玩法交流等等),又不定时开放了,有一群有趣有料的小伙伴在等你哦!进群方式:加我微信回复666