收藏 分享(赏)

第三章 抽象语法树.doc

上传人:11xg27ws 文档编号:6971261 上传时间:2019-04-28 格式:DOC 页数:8 大小:96.50KB
下载 相关 举报
第三章 抽象语法树.doc_第1页
第1页 / 共8页
第三章 抽象语法树.doc_第2页
第2页 / 共8页
第三章 抽象语法树.doc_第3页
第3页 / 共8页
第三章 抽象语法树.doc_第4页
第4页 / 共8页
第三章 抽象语法树.doc_第5页
第5页 / 共8页
点击查看更多>>
资源描述

1、1第三章 抽象语法树在现代编译器的构造过程中,前端主要实现从源程序到中间形式(Intermediate Representation)的转换,而编译器的后端用来完成从中间形式到具体目标机代码的转换,这是一种广泛采用的编译器构造模型。虽然源程序到目标程序的直接转换是可行的,但是使用独立于具体目标平台的中间形式有以下优点:(1)使用中间形式可以比较容易地构造面向不同目标平台和不同语言的编译器。在不改动已有编译器前端的情况下,为新的目标平台构造一个生成该平台目标程序的后端,就可以构造出新平台的编译器。同样对于一个新的语言,在不改动已有编译器后端的情况下,为新语言构造一个识别该语言的前端,就可以构造出

2、新语言的编译器。(2)针对中间形式,可以进行独立于目标平台的代码优化。这样可以生成较高质量的目标代码,在此基础上可以对目标代码进行平台相关的优化,进而生成更高质量的目标代码。使用中间形式的主要缺点是,产生中间代码的编译过程与不产生中间代码的编译过程相比在效率上会显得有些低。这是因为中间代码还要进行再一次的翻译才能生成目标代码。但是,增加一层中间形式可以使编译器更好地模块化,并且可以在中间形式上做很多优化,这些足以抵消两次翻译所带来的低效率。所以,很多现代的编译器都使用了中间形式,比较常见的中间形式有逆波兰表示,N 元表示和树形表示三种。由于,在本系统中,我们使用抽象语法树作为中间形式,所以不再

3、对前两种中间形式做以介绍,感兴趣的读者可以参考编译原理 (Alfred V.Aho 编著) 。3.1 树形表示树形表示是一种非常流行的中间形式,它与三元式表示有着密切的关系,三元式表示可以看成是树形表示的直接形式。例如,表达式 W*X+(Y+Z)的树形表示如图 3.1 所示:图 3.1 表达式 W*X+(Y+Z)的树形表示+*ZZY+XW2在现代编译器的构造过程中,经常使用抽象语法树(Abstract Syntax Tree)作为一种中间形式,这样做可以把翻译过程从语法分析过程中分离出来,使得层次非常清晰。引入抽象语法树是基于多方面原因的,其中的一个原因在于适于语法分析的文法可能并不反映语言成

4、分的自然层次结构。比如 Fortran 的文法可能把子程序看成是简单的语句序列,而这并不能反映出 DO 循环的嵌套。如果我们采用能够反映 DO 循环嵌套的树形表示,那么子程序的语义分析将会更容易一些。因此,很多编译器经常要构造语法树。在这里我们之所以称其为“抽象” 语法树,是因为抽象语法树的结构不依赖于被编译语言的原文法,也就是语法分析阶段所采用的文法。在语法分析过程中,为了能够适应摸中分析方法的需要,有时需要对文法进行等价的转换(比如,消除左递归,避免回溯等) ,这些转换在采用特定的分析方法进行语法分析时是有必要的,但是这样做同时也会带来一些问题。比如,会引入多余的非终结符和多余的产生式等,

5、所有这些多余的成分都会对下面的编译阶段产生一定的限制,甚至会使各阶段变得非常混乱。按照这些文法进行推导时,每一个正确的输入在理论上都对应一个依赖于这些文法的具体分析树。但是正如上面提到的,这种分析数不大适合直接使用,所以我们引入了抽象语法树。抽象语法树在语法分析和后面的各编译阶段之间建立了一个清晰的接口,它能够反映源程序本身的语法结构。基于以上原因,抽象语法树在现代编译器的构造中使用得越来越广泛,本系统也构造了抽象语法树。下面我们先简单的介绍一下语法分析树和抽象语法树,并对它们做以简单的比较。语法分析树也称为具体语法树,因为这种树中的一切都是明示的,完全而又具体,显示了如何根据相应上下文无关文

6、法推导出特定的单词序列。在我们知道了一个单词序列为合法之后,后续的编译阶段就不再需要语法分析树上的许多信息了。因此,语法分析结束以后,一般会将这种语法分析树转换为一棵抽象语法树(又称 AST,简称语法树) ,删除树内部的大部分 “人为”结点,并对剩下的结点标注有用的信息。附在特定节点上的标注被称为它的属性。例如语句 if(ab) a = a-b;的语法分析树和抽象语法树分别可表示成图 3.2 和图 3.3。图 3.2 语句 if(ab) a = a-b 的语法分析树=ifaZa+bab aZ ZZ3图 3.3 语句 if(ab) a = a-b 的抽象语法树在许多编译器里,带标注的语法树就是从

7、前端传递到后端的中间形式,而在另一些编译器里,语义分析器最后可能还要遍历这棵树,生成某种另外的中间形式。本系统将这种语法树作为中间表示,不再对它做一步的转换3.2 系统抽象语法树的节点表示 While 语句节点产生式:while-stmt while( expression ) statementwhile 语句的抽象语法树说明:对于 while 语句,根节点是 while,第一个孩子节点表示条件(expression),第二个孩子节点是条件为真的时候的执行语句(statement)。这些说明部分在下面的抽象语法树图中是很直观的表示,因此以下语句结点语法树将不再赘述。While语句expres

8、sion statementChild0 Child1图 3.4while 语句的抽象语法树 If 语句节点表示产生式:if-stmt if( expression ) statement else statementIf语句expression statement else Child0 Child1 Child2图 3.5 If 语句的抽象语法树If 语句条件部分 Then 部分 Else 部分4 函数声明节点产生式:fun-declaration ( void | int ) ID( params ) compound-stmt函数定义节点语句1 语句2sibling参数1 参数2sib

9、lingChild0 Child1函数名返回类型图 3.6 函数声明的语法树 表达式语句节点产生式:expression ID = expression | simple-expressionsimple-expression additive-expression relop additive-expression relop | = | = | != additive-expression term ( + | - ) term term factor ( * | / ) factor factor ( expression )| ID | call | NUM= + - ID ID图 3

10、.7 表达式语句的语法树 程序节点产生式:program var-declaration | fun-declaration 全局变量 函数 函数sibling sibling参数列表child childchild图 3.8 程序的语法树例:如下程序段代码:int pi;int add(int x, int y)5return x+y;void main() 语法分析结束后生成的抽象语法树如下图 3.9 所示:pi add mainsibling siblingChild【0 】 Child【1 】xsibling return+xChild【1 】Child【0 】yy图 3.9 生成的语

11、法树3.3 抽象语法树的设计在本章前面几节中,我们介绍了抽象语法树的基本概念,与语法分析树的比较以及在系统中抽象语法树的节点表示。在本节中,我们将详细讲解本系统中抽象语法树节点设计,并且对抽象语法树的实现代码做以解释。抽象语法树的节点类型如下所示:/抽象语法树的节点类型public enum NodeType FunDecl, VarDecl, Para,ADD, SUB, MUL, DIV, REQ, RLT, RGT, RNEQ, RNGT, RNLT,AssignStm, IfStm, IfElseStm, ElseStm, WhileStm, ReturnStm,FunCall, Co

12、nstID, VarID,OTHER, ERROR;在此基础上,我们再给出了抽象语法树的节点定义,见第二章表 2.1。下面,我们给出抽象语法树的实现代码并给出必要的解释。所给出的代码与文件 parser/Parser.cs 中的源代码略有不同,但是基本思路一致,为了便于读6者理解,parser/Parser.cs 特改写成以下代码形式:class Parser Token curtoken;void parse() curtoken = getNextToken(); /取得第一个 tokenTreeNode root = null;root = program(); /递规下降分析!构建语法

13、树,并返回根节点函数 parse():这个函数所做的工作就是从词法分析所生成的单词序列中取得第一个单词 Token,然后,调用 program()函数,构建抽象语法树,并返回抽象语法树的根节点;void match(TokenType expected)if(curtoken.TType = expected) curtoken=getNextToken();else ParseError();函数 match(TokenType expected):用来通过将当前单词类型与语法上应该出现的正确单词类型进行比较,检查是否有语法错误。如果没有语法错误,则从单词序列中取得下一个单词,以便后面继续进

14、行语法分析,构建抽象语法树使用,如果出现语法错误,则调用函数 ParseError()进行出错处理;TreeNode program() Token p, q; p = root;while(curtoken.TType!=TokenType.ENDFILE) if(curtoken.TType=TokenType.FunDecl) q=fun_decl();if(curtoken.TType=TokenType.VarDecl) q =var_decl();p.Sibling = q; p = p.Sibling;Return root;TreeNode var_decl() 函数 prog

15、ram():此函数的作用是进行递归下降分析,生成抽象语法树,返回抽象语法树的根节点 root。这个函数中的变量 p 用来记录前一次所生成的节点,变量 q 用来记录当前所生成的节点。TreeNode retnode, nextnode, curnode; retnode = curnode;retnode.NType = curnode.NType = NodeType.VarDecl;while(curtoken.TType!=TokenType.SEMI) Switch(curtoken.TType) case TokenType.INT: match(TokenType.INT); bre

16、ak;case TokenType.ID:nextnode.NodeStr = curtoken.str; curnode.Sibling = nextnode; curnode = nextnode;match(TokenType.ID);7break;case TokenType.COMMA:match(TokenType.COMMA); break;default: ParseError(); break; Match(TokenType.SEMI); Return retnode;函数 var_decl():这个函数实现了一个变量声明语句的抽象语法树节点的构建,并且返回其根节点 ret

17、node。这里的变量声明仅限于简单变量,且数据类型为整型。TreeNode fun_decl() TreeNode retnode; retnode.NType = NodeType. FunDecl;While(curtoken.TType!=TokenType. LPAREN) Switch(curtoken.TType) case TokenType.INT: case TokenType.VOID: retnode.retType = curtoken.str; match(curtoken.TType); break;case TokenType.ID: retnode.NodeSt

18、r = curtoken.str; match(TokenType.ID); break;default: ParseError(); break; match(TokenType.LPAREN);if(token.TType != TokenType.RPAREN) /匹配参数列表,第 1 个子节点 TreeNode paramsNode = param_list();retnode.child0 = paramsNode;match(TokenType.RPAREN);TreeNode stmtNode = compound_stmt();/函数体,第 2 个子节点 retode.child1 = stmtNode;return retnode;函数 fun_decl():此函数实现了函数定义的抽象语法树节点的构建,并且返回其根节点 retnode。while 循环体用来函数定义节点,即具有函数名和返回类型节点信息的语法节点。if 语句体用来生成函数定义节点的第一个子节点,参数列表节点。后面的代码完成函数定义节点的第二个子节点,函数体节点的构建。至此,我们对本系统抽象语法树生成过程的介绍就结束了,在这一章中,我们先后讲解了抽象语法树的基本概念,作用,并结合本系统说明了抽象语法树的设计与基本构建过程。8

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报