`
bengan
  • 浏览: 201740 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

抽象语法树(AST)

阅读更多
原文出自:http://blog.csdn.net/zhouhuozhi/archive/2009/06/07/4250258.aspx
抽象语法树(AST)
最近在做一个类JAVA语言的编译器,整个开发过程,用抽象语法树(Abstract SyntaxTree,AST)作为程序的一种中间表示,所以首先就要学会建立相对应源代码的AST和访问AST。Eclipse AST是Eclipse JDT的一个重要组成部分,定义在包org.eclipse.jdt.core.dom中,用来表示JAVA语言中的所有语法结构。
Eclipse AST的总体结构
1、org.eclipse.jdt.core.dom.AST(AST节点类)
Eclipse AST的工厂类,用于创建表示各种语法结构的节点。

2、org.eclipse.jdt.core.dom.ASTNode及其派生类(AST类)
用于表示JAVA语言中的所有语法结构,在实际使用中常作为AST上的节点出现。

3、org.eclipse.jdt.core.dom.ASTVisitor(ASTVisitor类)
Eclipse AST的访问者类,定义了统一的访问AST中各个节点的方法。
详细介绍:
一、AST节点类
整体结构包括CompilationUnit类(编译单元)、TypeDeclaration类(类型声明)、MethodDeclaration类(方法声明);
语句包括Block类(语句块)、ExpressionStatement类(表达式)、IfStatement(if语句)、WhileStatement类(while语句)、EmptyStatement类(空语句)、BreakStatement类和ContinueStatement类;
表达式包括MethodInvocation类(方法调用)、Assignment类(赋值表达式)(“=”、“+=”、“-=”、“*=”、“/=”)、InfixExpression类(中缀表达式)(“+”、“-”、“*”、“/”、“%”、“==”、“!=”、“<"、“<=”、“>=”、“&&”、“||”。)、 PrefixExpression类(前缀表达式)(“+”PLUS  “-”MINUS  “!”NOT)、ParenthesizedExpression类(带括号的表达式)、NumberLiteral类(整数)、Name类(simple)、MethodInvocation类(方法调用)。
二、AST类
关键是创建编译单元节点,创建类AST的实例。
AST ast = AST.newAST(JLS3);
三、ASTVisitor类
它提供与节点类有关的visit()方法和endVisit()法,与节点类无关的preVisit()方法和postVisit()方法。
boolean  visit( T node):这类方法如果返回true,则接着访问子节点。如果返回false,则不再访问子节点。
void endVisit(T node):这类方法在节点node的子节点已经被访问或者是在visit(node)返回false后调用。
void preVisit():这类方法在visit(node)之前被调用。
void postVisit():这类方法在endVisit(node)之后被调用。
在做简单解释器过程中,分析句子时我主要用到了上面的visit()和endVisit()方法,其中visit()方法是比较好理解的,主要是endVisit()方法在没有特定语法分析树的情况下分析是比较抽象的,所以下面我举几个例子分析。
endVisit()在node的子节点已被访问后调用型:
a、赋值语句分析为例:

i1 = 1;
i4 = i1;
它们对应语法树结构:
Expressionstatement

Assignment


simplename
numberLiteral




Expressionstatement
Assignment





simplename
simplename



实现程序:
int rightis_num = 1;
visit(Assignment n){
return true;
}
public void endVisit(Assignment n)//访问完所有的节点后,rightis_num已经能够确定
    {
        Expression string = n.getLeftHandSide();//返回表达式左部
        String simplename =((SimpleName) string).getIdentifier();//将变量串赋给simplename
        try
        { 
           if(rightis_num == 1)
           {
               Expression data1 = n.getRightHandSide();//返回表达式右部
               System.out.println(simplename);
               hm.put(simplename,new Integer(((NumberLiteral) data1).getToken()));//将变量及值加入hashmap
               System.out.println(hm.get(simplename));
        }
           else//右部为标识符
           { 
               Expression data2 = n.getRightHandSide();//返回表达式右部
               String rightname = ((SimpleName) data2).getIdentifier();
               hm.put(simplename,hm.get(rightname));
               System.out.println(hm.get(simplename));             
           }
        }
        catch(Exception e)
        {}
    }



对应源程序AST的建立
           
class Program{
static void main(){
    i = 10;
    }
}

/************实现方法************/

AST ast = AST.newAST(JLS3);

CompilationUnit cu = ast.newCompilationUnit();//CompilationUnit实例中包含一个TypeDeclaration

TypeDeclaration type = ast.newTypeDeclaration();//TypeDeclaration实例表示程序中的类
type.setName(ast.newSimpleName("Program"));

MethodDeclaration method = ast.newMethodDeclaration();//TypeDeclaration实例中添加类Program中的方法main();
method.setName(ast.newSimpleName("main"));
type.bodyDeclarations().add(method);
method.modifiers().add(
    ast.newModifier(Modifier.ModifierKeyword.STATIC_KEYWORD));//设置方法main()的modifier修饰语为static
method.setReturnType2(ast.newPrimitiveType(PrimitiveType.VOID));//设置方法main()的返回类型为void

Block mainBody = ast.newBlock();
method.setBody(mainBody);//构造main函数的函数体mainBody

//向方法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中,结合AST节点的accept()方法和ASTVisitor实例,假设待访问的AST树的根节点为root,则调用root.accept()就可以启动对这棵AST树的遍历。

总结:做这个简单解释器的主要目的是熟悉程序源代码对应AST的映射,创建对应的AST方法都比较的固定,问题不大。难主是难在遍历树上,分析不同的语句结构,需要重写Visit()方法,同时要适当利用endVisit()方法增加一些控制变量,以决定应该解释句子的哪一分支。到现在对preVisit()和postVisit()方法仍然不怎么了解,在接下来的编译器开发中仍需慢慢摸索。熟悉了AST相关知识,后续工作可以展开了。
分享到:
评论

相关推荐

    C语言的词法分析和抽象语法树(AST)分析器.zip

    C语言的词法分析和抽象语法树(AST)分析器 C语言的词法分析和抽象语法树(AST)分析器是一个项目,旨在实现一个能够识别C语言中的词法单元并构建抽象语法树的程序。这个项目通常包括以下步骤: ### 项目介绍: **目标**...

    用于Java程序的抽象语法树类Abstractyntaxreelassesororking1

    在编程语言解析和编译领域,抽象语法树(Abstract Syntax Tree,AST)是一种重要的数据结构,它将源代码转换为一个树形结构,便于分析和处理。在Java程序中,AST类用于表示程序的语法结构,使得我们可以对代码进行...

    浅析AST抽象语法树及Python代码实现

    ### AST抽象语法树简介 #### 一、AST概念解析 抽象语法树(Abstract Syntax Tree,简称AST)是一种用于表示程序源代码的树形结构。它不仅限于编程语言的源代码,还可以应用于其他任何形式的文本,如数学公式或自然...

    自定义抽象语法树JSON模板

    在编程领域,抽象语法树(Abstract Syntax Tree,简称AST)是一种数据结构,它代表了源代码的结构。自定义抽象语法树JSON模板是为特定语言或解析任务构建的,用于将源代码转换成更容易处理的形式。这个过程通常发生...

    一种基于抽象语法树的C#源代码SQL注入漏洞检测算法.pdf

    《一种基于抽象语法树的C#源代码SQL注入漏洞检测算法》这篇学术论文探讨了如何利用抽象语法树(AST)技术来检测C#源代码中的SQL注入漏洞。SQL注入是网络安全领域的一个重大威胁,它允许攻击者通过输入恶意SQL语句来...

    flora-sql-parser:将SQL(选择)语句解析为抽象语法树(AST),并将AST转换回SQL

    Flora SQL解析器 将简单SQL语句解析为抽象语法树(AST),然后将其转换回SQL。用法为SQL语句创建AST const { Parser } = require ( 'flora-sql-parser' ) ;const parser = new Parser ( ) ;const ast = parser . ...

    javaparser,Java 9解析器和抽象语法树-.zip

    JavaParser是一个强大的开源项目,专为Java开发人员设计,提供了对Java源代码的解析和抽象语法树(AST)分析功能。这个项目支持从Java 1.0到Java 13的多个版本,允许开发者深入理解代码结构,进行复杂的代码操作和...

    ast, 用于处理抽象语法树的库.zip

    ast, 用于处理抽象语法树的库 AST是一个用于处理不可变抽象语法树的小型库。安装$ gem install ast用法参见 GitHub 或者 rdoc.info 文档。fork创建你的特征分支( git checkou

    基于抽象语法树和改进粒子群算法的代码同源性分析

    本文将详细探讨基于抽象语法树(Abstract Syntax Tree, AST)和改进粒子群优化算法(Improved Particle Swarm Optimization, IPSO)的代码同源性分析方法,并结合ANTLR工具进行解析。 首先,让我们理解抽象语法树。...

    基于C语言构造一个高级语言的子集的编译器【100012141】

    关键技术:Flex、Bison、C 语言基本知识、抽象语法树 AST、mips32 汇编指令、终端相关操作。 总体说明:本实验由四个部分组成:词法分析、语法分析、语义分析、中间代码生成、目标代码生成。首先将设定的识别词法...

    LISP表达式的抽象语法树

    当我们谈论“LISP表达式的抽象语法树”时,我们指的是将LISP代码转化为一种图形化表示,即抽象语法树(Abstract Syntax Tree,AST),以更好地理解和处理这些表达式。 抽象语法树是编译器和解释器设计中的一个重要...

    Java9解析器和抽象语法树

    这些元素随后被抽象语法树(AST)所表示,它是一个树状数据结构,每个节点代表源代码中的一个语法构造。 Java 9引入了一些改进和优化,使得解析器和AST处理更加高效。在深入理解这些概念之前,我们需要先了解一些...

    LISP表达式的抽象语法树分析器.rar

    抽象语法树(Abstract Syntax Tree,AST)是编译原理中的一个重要概念,它用于表示源代码的结构,方便进行后续的编译或解释过程。 在这个"**LISP表达式的抽象语法树分析器**"中,我们主要关注的是如何将LISP表达式...

    PHP7新特性之抽象语法树(AST)带来的变化详解

    PHP7新版本中引入了抽象语法树(AST)的概念,这是其核心架构中的一次重要变动。AST的加入,不仅在技术层面上为PHP带来了显著的变化,而且在程序执行效率和代码语义上也有所影响。 在之前的PHP5版本中,从源代码到...

    asty:抽象语法树 (AST) 数据结构

    抽象语法树 (AST) 数据结构 安装 $ npm install asty 关于 ASTy 是 JavaScript 的抽象语法树 (AST) 数据结构库,即它提供了一种分层数据结构,用于保存任意形式语言的语法抽象。 它通常与像这样的解析器生成器结合...

    stoke:生成Bash命令的抽象语法树(AST)

    生成命令的抽象语法树(AST)。 根据Bash引用规则的子集标记给定命令 检测格式错误的命令 , 为什么 主要是这样写的: 作为编写基于严格语法规则的解析器的练习 作为一个从头开始构建Bash外壳的大型项目的一部分 ...

Global site tag (gtag.js) - Google Analytics