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[]{12});
        System.out.println("Groovy result=" + result);
    }

}

总结:

本文深入浅出地介绍了Java AST的概念、应用和操作,并通过示例和图解等形式,使读者更直观地理解和掌握这一技术。Java AST在代码分析、重构、生成等方面有着广泛的应用,是编程任务中不可或缺的一部分。

写在最后

时隔2个月,某鱼群再次限时开放了 。

Java技术指北读者交流群,(摸鱼,白嫖技术课程ast树,最新时事,GPT玩法交流等等),又不定时开放了,有一群有趣有料的小伙伴在等你哦!进群方式:加我微信回复666

ast树_ast树_ast树

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注