IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> java 抽象语法树(AST)之概述 -> 正文阅读

[Java知识库]java 抽象语法树(AST)之概述

一、AST

AST? abstract syntax tree (抽象语法结构树),是对java语言的一种抽象,每个节点都能对应到一种java语法,最终一个java文件就是由棵节点树构成

二、Tree

Tree是一个接口,是AST节点的抽象,内部有一个最重要的枚举Kind,定义了java中的每条语句的格式,也是对应着AST的一个节点

以下均为子接口,每个结构都定义了语法节点类型

Tree

  • WildcardTree
  • TypeParameterType
  • StatementTree? ? ? (一个完整的语句,比如简单的"int a = 1;",注意最后的“;”)
    • ThrowTree
    • ReturnTree
    • TryTree
    • ContinueTree
    • BreakTree
    • BlockTree
    • DoWhileLoopTree
    • ClassTree
    • VariableTree
    • WhileLoopTree
    • ForLoopTree
    • SwitchTree
    • SynchronizedTree
    • EnhancedForLoopTree
    • LabeedStatementTree
    • AssertTree
    • EmptyStatementTree
    • IfTree
    • ExpressionStatementTree
  • CatchTree
  • MethodTree
  • ArrayTypeTree
  • UnionTypeTree
  • ModifiersTree
  • ParameterizedTypeTree
  • CaseTree
  • ExpressionTree? ? ? ?(一个非完整的语句,比如简单的"a = 1",注意最后没有“;”)
    • MemberReferenceTree
    • LambdaExpressionTree
    • UnaryTree
    • MethodInvocationTree
    • AnnotatedTypeTree
    • CompoundAssignmentTree
    • BinaryTree
    • ErroneousTree
    • MemberSelectTree
    • ArrayAccessTree
    • TypeCastTree
    • NewClassTree
    • ConditionalExpressionTree
    • ParenthesizedTree
    • AnnotationTree
    • NewArrayType
    • InstanceOfTree
    • IdentifierTree
    • AssignmentTree
    • LiteralTree
  • CompilationUnitTree
  • IntersectionTypeTree
  • PrimitiveTypeTree
  • Import

三、Kind

AST 节点类型,对应着java的语法

枚举类型Tree节点(就是上面列出的接口)定义示例
ANNOTATED_TYPEAnnotatedTypeTree

注解类型,可以用在任何类型上

注解的Target为:TYPE_PARAMETER

TYPE_USE

@NotNull String
ANNOTATIONAnnotationTree普通的注解

@Data

@JsonProperties(value="sdf")

TYPE_ANNOTATIONAnnotationTree跟ANNOTATION,待验证有什么区别
ARRAY_ACCESSArrayAccessTree数组访问array[3]
ARRAY_TYPEArrayTypeTree数组类型int[]
ASSIGNMENTAssignmentTree赋值a = 1
BLOCKBlockTree语句块

{}

{ statements }

static { statements }

BREAKBreakTreebreak

break;

break label;

CASECaseTreecase 语句

case expression:statements

default: statements

CATCHCatchTreecatch 语句

catch(parameter)? block

注:这些语句会有嵌套问题

CLASS

INTERFACE

ENUM

ANNOTATION_TYPE

ClassTreeclass 定义modifiers class simpleName typeParameters
? ? ? ?extends extendsClause
? ? ? ?implements implementsClause
{
? ?<em>members</em>
}
COMPILATION_UNITCompilationUnitTree

一个编译单元

包括源文件和package-info.java

CONDITIONAL_EXPRESSIONConditionalExpressionTree三元运算符a == 1 ? 1 : 0
CONTINUEContinueTreecontinue 语句

continue;

continue label;

DO_WHILE_LOOPDoWhileLoopTreedo...while
ENHANCED_FOR_LOOPEnhancedForLoopTree增强forfor(int i: intlist) { statement }
EXPRESSION_STATEMENTExpressionStatementTree语句
MEMBER_SELECTMemberSelectTree对象.操作aClass.aparams
MEMBER_REFERENCEMemberReferenceTree成员引用表达式
FOR_LOOPForLoopTreefor循环
IDENTIFIERIdentifierTree识别符,与literal区分开

a = 1

a 就是一个identifier

IFIfTree
IMPORTImportTree
INSTANCE_OFInstanceOfTreeinstanceof 表达式
LABELED_STATEMENTLabeledStatementTreelabel语法label : statement
METHODMethodTree方法定义方法
modifiers typeParameters type name (parameters )
? ?body
?
注解
modifiers type name () default defaultValue
METHOD_INVOCATIONMethodInvocationTreemethod invoke语法
MODIFIERSModifiersTree

修饰符(Modifier)

包括注解

NEW_ARRAYNewArrayTree
NEW_CLASSNewClassTree
LAMBDA_EXPRESSIONLambdaExpressionTreelambda表达式
PRIMITIVE_TYPEPrimitiveTypeTree基础类型
RETURNReturnTreereturn
EMPTY_STATEMENTEmptyStatementTree空的";"
SWITCHSwitchTree
SYNCHRONIZEDSynchronizedTree
THROWThrowTree
TRYTryTree
PARAMETERIZED_TYPEParameterizedTypeTree泛型List<Integer>
UNION_TYPEUnionTypeTree多变量声明

try {

}catch(Exception e1 | Exception e2){

}

INTERSECTION_TYPEIntersectionTypeTreeT extends MyA & MyB
TYPE_CASTTypeCastTree强转语句(int)a
TYPE_PARAMETERTypeParameterTree
VARIABLEVariableTree变量

modifiers type name initializer ;

modifiers type qualified-name.this

WHILE_LOOPWhileLoopTree

POSTFIX_INCREMENT

POSTFIX_DECREMENT

PREFIX_INCREMENT

PREFIX_DECREMENT

UNARY_PLUS

UNARY_MINUS

BITWISE_COMPLEMENT

LOGICAL_COMPLEMENT

UnaryTree运算符

++、--、+、-、~、!、*、/、%

MULTIPLY

DIVIDE

REMAINDER

PLUS

MINUS

LEFT_SHIFT

RIGHT_SHIFT

UNSIGNED_RIGHT_SHIFT

LESS_THAN

GREATER_THAN

LESS_THAN_EQUAL

GREATER_THAN_EQUAL

EQUAL_TO

NOT_EQUAL_TO

AND

XOR

OR

CONDITIONAL_AND

CONDITIONAL_OR

BinaryTree两元运算

MULTIPLY_ASSIGNMENT

DIVIDE_ASSIGNMENT

REMAINDER_ASSIGNMENT

PLUS_ASSIGNMENT

MINUS_ASSIGNMENT

LEFT_SHIFT_ASSIGNMENT

RIGHT_SHIFT_ASSIGNMENT

UNSIGNED_RIGHT_SHIFT_ASSIGNMENT

AND_ASSIGNMENT

XOR_ASSIGNMENT

OR_ASSIGNMENT

CompoundAssignmentTree赋值运算符+=、-=、*=

INT_LITERAL

LONG_LITERAL

FLOAT_LITERAL

DOUBLE_LITERAL

BOOLEAN_LITERAL

CHAR_LITERAL

STRING_LITERAL

NULL_LITERAL

LiteralTree字面值a =? 1? (1就是)
OTHERnull

?四、JCTree

com.sun.tools.javac.tree.JCTree 是Tree的一个抽象实现类,有各种实现类,代表着一个个的AST节点

JC具体类实现TreeTagKind备注
LetExprLETEXPR不支持
JCErroneousErroneousTreeERRONEOUSERRONEOUS
JCAnnotatedTypeAnnotatedTypeTreeANNOTATED_TYPEANNOTATED_TYPE
JCModifiersModifiersTreeMODIFIERSMODIFIERS?
JCAnnotationAnnotationTree?
JCTypeParameterTypeParameterTreeTYPEPARAMETERTYPE_PARAMETER
JCTypeIntersectionIntersectionTypeTreeTYPEINTERSECTIONINTERSECTION_TYPE
JCTypeUnionUnionTypeTreeTYPEUNIONUNION_TYPE
JCTypeApplyParameterizedTypeTreeTYPEAPPLYPARAMETERIZED_TYPE
JCArrayTypeTreeArrayTypeTreeTYPEARRAYARRAY_TYPE
JCPrimitiveTypeTreePrimitiveTypeTreeTYPEIDENTPRIMITIVE_TYPE?
JCLiteralLiteralTreeLITERAL

INT_LITERAL

LONG_LITERAL

... 以LITERAL结尾的

?
JCIdentIdentifierTreeIDENTIDENTIFIER?
JCMemberReferenceMemberReferenceTreeREFERENCEMEMBER_REFERENCE
JCFieldAccessMemberSelectTreeSELECTMEMBER_SELECT?
JCArrayAccessArrayAccessTreeINDEXEDARRAY_ACCESS?
JCInstanceOfInstanceOfTreeTYPETESTINSTANCE_OF
JCTypeCastTypeCastTreeTYPE_CASTTYPECAST
JCBinaryBinaryTree根据操作符定根据tag映射
JCAssignOpCompoundAssignmentTree

赋值,根据操作符定

支持的是 “+=”这种

根据tag映射
JCAssignAssignmentTree

ASSIGN

支持的是直接赋值

ASSIGNMENT?
JCParensParenthesizedTreePARENSPARENTHESIZED
JCLambdaLambdaExpressionTreeLAMBDALAMBDA_EXPRESSION
JCNewArrayNewArrayTreeNEWARRAYNEW_ARRAY
JCNewClassNewClassTreeNEWCLASSNEW_CLASS
JCMethodInvocationMethodInvocationTreeAPPLYMETHOD_INVOCATION
JCAssertAssertTreeASSERTASSERT
JCThrowThrowTreeTHROWTHROW?
JCReturnReturnTreeRETURNRETURN?
JCContinueContinueTreeCONTINUECONTINUE
JCBreakBreakTreeBREAKBREAK
JCExpressionStatementExpressionStatementTreeEXECEXPRESSION_STATEMENT
JCIfIfTreeIFIF
JCConditionalConditionalExpressionTreeCONDEXPRCONDITIONAL_EXPRESSION
JCCatchCatchTreeCATCHCATCH
JCTryTryTreeTRYTRY
JCSynchronizedSynchronizedTreeSYNCHRONIZEDSYNCHRONIZED
JCCaseCaseTreeCASECASE
JCSwitchSwitchTreeSWITCHSWITCH
JCLabeledStatementLabeledStatementTreeLABELLEDLABELED_STATEMENT
JCEnhancedForLoopEnhancedForLoopTreeFOREACHLOOPENHANCED_FOR_LOOP
JCForLoopForLoopTreeFORLOOPFOR_LOOP
JCWhileLoopWhileLoopTreeWHILELOOPWHILE_LOOP
JCDoWhileLoopDoWhileLoopTreeDOLOOPDO_WHILE_LOOP
JCBlockBlockTreeBLOCKBLOCK
JCSkipEmptyStatementTreeSKIPEMPTY_STATEMENT
JCVariableDeclVariableTreeVARDEFVARIABLE?
JCMethodDeclMethodTreeMETHODDEFMETHOD?
JCClassDeclClassTreeCLASSDEF

ANNOTATION_TYPE

INTERFACE

ENUM

CLASS

?
JCImportImportTreeIMPORTIMPORT?
JCCompilationUnitCompilationUnitTreeTOPLEVELCOMPILATION_UNIT

五、JC类的Factory

细心阅读会发现,各种JC类的构造函数都是protected,也就是说,并不能直接进行初始化,所以现在要使用Factory,Factory是各种JC类的工厂定义

六、TreeMaker

TreeMaker实现了Factory接口,所以我们它会是我们经常使用的一个类

还需要关注的一个Names,这个基本是创建一个节点的开始

Names: 用来存储和表示解析后的词法,每个字符集合都会是一个Name对象,所有的对象都存储在Name.Table内部类中。

在学习以下内容时,一定要熟练掌握JCIdent和Names。

Javac编译原理 - wade&luffy - 博客园


?

javac源码笔记与简单的编译原理 | Ren's Time Overflow Skyline ^_^

深入分析 Javac 编译原理 - 知乎

6.1、添加 import

// import com.leisure.lombok.thrift.AstTreeClass
// 获取标识符
JCTree.JCIdent jcIdent = treeMaker.Ident(names.fromString("com.leisure.lombok.thrift"));
// 获取标识符
Name className = names.fromString("AstTreeClass");
// 定义访问
JCTree.JCFieldAccess jcFieldAccess = treeMaker.Select(jcIdent, className);
// 添加import节点
JCTree.JCImport anImport = treeMaker.Import(jcFieldAccess, false);
// 加入AST树种
jcCompilationUnit.defs = jcCompilationUnit.defs.append(anImport);

6.2、定义属性

默认构造函数

//private AstTreeClass variable = new AstTreeClass()
        // new AstTreeClass()
        JCTree.JCNewClass newClass = treeMaker.NewClass(null, null, treeMaker.Ident(names.fromString("AstTreeClass")), List.nil(), null);

        // private AstTreeClass variable = ...
        JCTree.JCVariableDecl variableDecl = treeMaker.VarDef(treeMaker.Modifiers(Modifier.PRIVATE.ordinal()),
                names.fromString("variable"), treeMaker.Ident(names.fromString("AstTreeClass")), newClass);

带参数的构造函数

使用这个我们就可以实现@Slf4j了(当然了,还需要有插件,才能真正像@Slf4j一样使用)

//public static final AstTreeClass staticVariable = new AstTreeClass(1)
        JCTree.JCLiteral constantOne = treeMaker.Literal(1);
        JCTree.JCNewClass newClass1 = treeMaker.NewClass(null, null, treeMaker.Ident(names.fromString("AstTreeClass")), List.of(constantOne), null);

        JCTree.JCVariableDecl staticVariableDecl = treeMaker.VarDef(
                treeMaker.Modifiers(Flags.PUBLIC + Flags.STATIC + Flags.FINAL),
                names.fromString("staticVariable"),
                treeMaker.Ident(names.fromString("AstTreeClass")),
                newClass1
        );

6.4、添加方法

            String name = variableDecl.name.toString();
            JCTree.JCExpression varType = variableDecl.vartype;
            // getter,假设name长度大于1
            String getterMethodName = "get" + name.substring(0, 1).toUpperCase() + name.substring(1);
            // this.name
            JCTree.JCExpression thisName = treeMaker.Select(treeMaker.This(classDecl.sym.type), names.fromString(name));
            JCTree.JCReturn jcReturn = treeMaker.Return(thisName);
            // public type getName() {return this.name;}
            JCTree.JCMethodDecl getter = treeMaker.MethodDef(
                    treeMaker.Modifiers(Flags.PUBLIC), // 访问标识
                    names.fromString(getterMethodName), // 方法名字
                    varType,                            // 返回类型
                    List.nil(),                          // 泛型形参列表
                    List.nil(),                        // 参数列表
                    List.nil(),                        // 异常列表
                    treeMaker.Block(0, List.of(jcReturn)), // block
                    null                   // 默认方法
            );
            // setter
            // public void setName(nameType name) {this.name = name;}
            String setterMethodName = "set" + name.substring(0, 1).toUpperCase() + name.substring(1);
            // 这里只是生成了this.name = name表达式
            JCTree.JCAssign assign = treeMaker.Assign(thisName, treeMaker.Ident(names.fromString(name)));
            // 生成一条语句 this.name = name;
            JCTree.JCExpressionStatement assignStat = treeMaker.Exec(assign);
            JCTree.JCMethodDecl setterMethodDecl = treeMaker.MethodDef(
                    treeMaker.Modifiers(Flags.PUBLIC),     // 访问标识
                    names.fromString(setterMethodName),    // 方法名
                    treeMaker.TypeIdent(TypeTag.VOID),                     // 返回类型
                    List.nil(),                    // 泛型形参列表
                    List.of(treeMaker.VarDef(
                            treeMaker.Modifiers(Flags.PARAMETER),   // 普通参数
                            variableDecl.name,
                            varType,
                            null   // 初始化为空,方法入参时为空即可
                            )
                    ), // 参数列表
                    List.nil(), // 异常列表
                    treeMaker.Block(0, List.of(assignStat)), // 方法体
                    null //默认方法
            );

解决TreeMaker AssertionError: Value of x -1_你倒是跑啊的博客-CSDN博客

TreeMaker? -> JCTree -> Tree?,接下来的一系列就是应用了

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-04-24 09:15:04  更:2022-04-24 09:20:12 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 2:31:03-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码