是源代码的抽象语法结构的树状表现形式,这里特指编程语言的源代码。树上的每个节点都表示源代码中的一种 结构。抽象语法树(Abstract Syntax Tree ,AST)作为程序的一种中间表示形式,在程序分析等诸多领域有广泛的应用 利用抽象语法树可以方便地实现多种源程序处理工具,比如源程序浏览器、智能编辑器、语言翻译器等.
在AST节点类中,只提供获取父节点的方法,即 ASTNode getParent( ) 而没有提供设置父节点的方法,
这是因为对节点的parent域的设置是伴随着将该节点设置为其他节点的子节点而自动进行的。一个新创建的AST节点
是没有设置其父节点的。当节点A通过形如setCHILD方法,如A.setPackage(B)方法,或者通过序列的add或set方法,
如A.types( ).add(B)方法,将节点B设为自己的孩子时,B节点的parent域将自动设置为对A节点的引用;对于那些
因上述操作导致不再是A节点的子节点来说,其parent域将被自动设置为null。每个AST节点及其子节点只能归属于
一棵AST树。如果将一棵AST树中的某个AST节点添加到另一棵AST树中,则必须复制这个节点及其所有的子孙节点,
以保证这些节点只属于一棵AST树。此外,AST树中不能含有环,如果某些操作会导致AST有环,则这些操作将失败。
为支持对源程序的分析和类型检查等,每个AST节点还含有一组位标志(用一个int型数表示) 用来传播与该
节点有关的附加信息,这些位标志可以通过节点的以下方法来存取:
void setFlags(int flags) 、int getFlags( ) 。
此外,Eclipse AST还支持访问者模式,每个AST节点都含有方法: void accept(ASTVisitor visitor) 用于统一
表示对当前节点访问时所要执行的任务,这个任务由参数visitor来给定。你可以进一步了解ASTVisitor类以及访问
者模式来了解对AST树的访问。
2.AST类:
org.eclipse.jdt.core.dom.AST是AST节点的工厂类,即它提供一系列形如 TYPE newTYPE( ) 的工厂方法,用来创建名为TYPE的Eclipse AST节点类的实例,新创建的节点并没有设置父节点。例如,方法 CompilationUnit newCompilationUnit( ) 用来创建由这个AST所拥有的一个编译单元节点。 要使用这些方法,首先需要创建AST类的实例: AST ast = AST.newAST(AST.JLS3); 其中,参数AST.JLS3指示所生成的ast包含处理JLS3(Java语言规范第3版)的AST API。JLS3是Java语言所有早期版本的超集,JLS3 API可以用来处理直到Java SE 6(即JDK1.6)的Java程序。
3.AST类:
org.eclipse.jdt.core.dom.ASTVisitor是AST树的访问者类,它提供一套方法来实现对给定节点的访问。这套方法中有两组是与具体的AST节点类T相关的,即visit方法和endVisit方法,有两个是与具体的AST节点类无关的,即preVisit方法和postVisit方法。这些方法都通过参数接收一个AST节点node,然后对这个节点进行访问以执行一些操作。当你需要对AST树实现特定的访问功能时,你只需要结合实际需求设计和实现ASTVisitor类的子类就可以了。例如,在本章的课程设计中,你需要实现ASTVisitor类的派生类InterpVisitor,在其中重写(override)与需要解释执行的语法结构相对应的visit( )方法。
在这一节中,我们将演示如何利用Eclipse AST手工构建如下的SimpleMiniJOOL程序的AST中间表示。
class Program { static void main() { i = 10; } }首先,你需要通过Eclipse AST工厂类中的方法newAST()建立一个AST实例: AST ast = AST.newAST(JLS3); 利用这个AST实例,就可以按如下的方法创建各种AST节点,并构建完整的抽象语法树。 然后,利用Eclipse AST工厂类中的各种创建方法按如下步骤创建所需要的AST节点:1) 整个SimpleMiniJOOL程序构成一个CompilationUnit:
CompilationUnit cu = ast.newCompilationUnit();
2) 在CompilationUnit实例中包含一个TypeDeclaration,表示程序中的类Program:
TypeDeclaration type = ast.newTypeDeclaration( ); type.setName(ast.newSimpleName(“Program”)); // 定义类的名字
3) 在这个TypeDeclaration实例中添加类 Program中的方法main():
MethodDeclaration method = ast.newMethodDeclaration( ); method.setName(ast.newSimpleName(“main”));
type.bodyDeclarations().add(method);
// 设置方法main()的modifier为static
method.modifiers().add( ast.newModifier(Modifier.ModifierKeyword.STATIC_KEYWORD));
// 设置方法main()的返回类型为void method.setReturnType2(ast.newPrimitiveType(PrimitiveType.VOID));
4) 构造main函数的函数体
mainBody Block mainBody = ast.newBlock(); method.setBody(mainBody);
5) 向方法main函数体mainBody中添加语句
Assignment assign = ast.newAssignment(); // 构建赋值表达式 assign.setLeftHandSide(ast.newSimpleName("i")); // 设置赋值表达式的左值为i assign.setOperator(Assignment.Operator.ASSIGN); // 设置赋值表达式的赋值算符为 assign.setRightHandSide(ast.newNumberLiteral("10")); // 设置赋值表达式的右值为数字10
ExpressionStatement statement = ast.newExpressionStatement(assign);// 由赋值表达式构建语句,
mainBody.statements().add(statement); //并把这个语句加入方法Main()的函数体
至此,用Eclipse AST表示的SimpleMiniJOOL程序的抽象语法树就构建完毕lab1/src/edu/ustc/cs/compile/interpreter/TestCase.java中的createSampleAST( )方法给出了构建一个简单SimpleMiniJOOL程序对应的AST的完整示例。 需要再次强调的是,使用Eclipse AST构建的抽象语法树在拓扑结构上必须是无环的。无论是手工构建AST还是自动构建AST,你都需要小心的检查自己的代码,避免违反这个原则。
<本文参考:《Eclipse AST(抽象语法树)使用指南》