收藏 分享(赏)

第08章语法制导翻译和中间代码生成.ppt

上传人:hyngb9260 文档编号:8129186 上传时间:2019-06-10 格式:PPT 页数:78 大小:637KB
下载 相关 举报
第08章语法制导翻译和中间代码生成.ppt_第1页
第1页 / 共78页
第08章语法制导翻译和中间代码生成.ppt_第2页
第2页 / 共78页
第08章语法制导翻译和中间代码生成.ppt_第3页
第3页 / 共78页
第08章语法制导翻译和中间代码生成.ppt_第4页
第4页 / 共78页
第08章语法制导翻译和中间代码生成.ppt_第5页
第5页 / 共78页
点击查看更多>>
资源描述

1、1,第8章 语法制导翻译和中间代码生成,属性文法 语法制导翻译方法的基本思想 几种典型的中间代码形式 一些语法成分的翻译,2,语义分析的两个功能,第一,审查每个语法结构的静态语义,即验证语法结构合法的程序是否真正有意义。有时把这个工作称为静态语义分析或静态审查. 第二,如果静态语义正确,语义处理则要执行真正的翻译,即,或者将源程序翻译成程序的一种中间表示形式(中间代码),或者将源程序翻译成目标代码。,3,静态语义分析, 类型检查。验证程序中执行的每个操作是否遵守语言的类型系统的过程.,编译程序必须报告不符合类型系统的信息。 控制流检查。控制流语句必须使控制转移到合法的地方。例如,在C语言中br

2、eak语句使控制跳离包括该语句的最小while、for或switch语句。如果不存在包括它的这样的语句,则就报错。 一致性检查。在很多场合要求对象只能被定义一次。例如Pascal语言规定同一标识符在一个分程序中只能被说明一次,同一case语句的标号不能相同,枚举类型的元素不能重复出现等等。 相关名字检查。有时,同一名字必须出现两次或多次。例如,Ada 语言程序中,循环或程序块可以有一个名字,出现在这些结构的开头和结尾,编译程序必须检查这两个地方用的名字是相同的。 名字的作用域分析。,4,动态语义分析,如果静态语义正确,语义处理则要执行真正的翻译,即,或者将源程序翻译成程序的一种中间表示形式(中

3、间代码),或者将源程序翻译成目标代码。,5,语义的形式化描述工具,文法模型- 属性文法 命令式或操作式模型 - 操作语义学 应用式模型-指称语义学 公理式模型-公理语义学 规格说明模型-代数数据类型,6,8.1 属性文法,属性文法的定义三元组:(,) 是上下文无关文法 属性的有穷集 关于属性的断言和谓词,7,用法,针对语义,为文法符号设置属性 终结符使用单词的属性 为每个产生式设置语义规则 描述各属性的关系,8,例8-1 计算器的设计,编制算术表达式的文法 引入属性表示语义信息 将值 val 作为表达式 E、项 T 和因子 F 的属性 用语义规则描述表达式的求值,9,属性文法(语法制导定义),

4、L E print( E.val ) E E1 + T E.val := E1.val + T.val E T E.val := T.val T T1 * F T.val := T1.val * F.val T F T.val := F.val F ( E ) F.val := E.val F digit F.val := digit.lexval lexval 是单词 digit 的属性,10,例8-3 3*5+4 的 语法树与属性计算,11,例8-2 说明语句类型信息统计,方法 编写说明语句的文法 将类型信息作为类型描述 T 的属性 type 和变量表 L 的属性 in。 目的 分析说明语

5、句 D,为变量指定类型,12,语法制导定义,D T L L.in := T.type T int T.type := integer T real T.type := real L L1,id L1.in := L.inaddtype( id.entry, L.in ) L id addtype( id.entry, L.in ) entry 单词 id 的属性 addtype 在符号表中为变量添加类型信息,13,例8-4 real id1,id2,id3 的分析树和属性计算,addtype,addtype,addtype,14,句子 int id1,id2 的语法树,使用 表示属性的传递情况

6、。,15,属性分类:,综合属性 从其子结点的属性值计算出来的; 如:E.val、T.type 继承属性 从其兄弟结点和父结点的属性值计算出来的 如:L.in 固有属性(单词属性),16,1、文法非终结符既有综合属性,也可有继承属性; 2、开始符号没有继承属性; 3、终结符只有综合属性,由词法分析器提供。,几点说明:,17,仅包括综合属性 对于所有 1 2 n, 的属性计算仅用1n 的属性 如:算术表达式求值的属性文法,S-属性定义:,18,L-属性定义:,其属性可用深度优先的顺序从左至右计算 对于所有 1 2 n i 属性计算仅使用 1 2 i-1 的属性 如:说明语句的属性文法,19,翻译模

7、式 定义 翻译模式是语法制导定义的一种便于翻译的书写形式。其中属性与文法符号相对应,语义规则或语义动作用花括号 括起来,可被插入到产生式右部的任何合适的位置上。 这是一种语法分析和语义动作交错的表示法,他表达在按深度优先遍历分析树的过程中何时执行语义动作。 翻译模式给出了使用语义规则进行计算的顺序。可看成是分析过程中翻译的注释。,20,例 一个简单的翻译模式ETR Raddop Tprint(addop.lexeme)R1| Tnumprint(num.val) 把语义动作看成终结符号,输入9-5+2,其分析树如下页图,当按深度优先遍历它,执行遍历中访问的语义动作,将输出9 5 - 2 + 它

8、是输入表达式9-5+2的后缀式。,21,E,T,9,T,Pt(9),R,Pt(-),Pt(+),R,-,5,Pt(5),+,T,2,Pt(2),R,9-5+2的带语义动作的分析树,ETR,Raddop Tprint(addop.lexeme)R1|,Tnumprint(num.val),22,设计翻译模式(根据语法制导定义),分两种情况: 1、只需要综合属性的情况 2. 既有综合属性又有继承属性,23,为每一个语义规则建立一个包含赋值的动作,并把这个动作放在相应的产生式右边的末尾。 例如:TT1*F Tval:=T1 val*F valTT1*F Tval:=T1 val*F val,1. 只

9、需要综合属性的情况:,24,产生式右边的符号的继承属性必须在这个符号以前的动作中计算出来。 一个动作不能引用这个动作右边符号的综合属性。 产生式左边非终结符号的综合属性只有在它所引用的所有属性都计算出来以后才能计算。计算这种属性的动作通常可放在产生式右端的末尾。,2. 既有综合属性又有继承属性,25,下面的翻译模式不满足要求,不满足第1)个条件:SA1A2 A1in:=1; A2 in:=2A a print(A in) ,可以看出,按深度优先遍历输入串aa的语法树,当要打印属性A.in时,该属性还没有定义。也就是说,从S开始按深度优先遍历A1和A2子树之前,A1.in和A2.in的值还未赋值

10、。,26,如果计算A1.in和A2.in的值的动作分别被嵌入在产生式SA1A2 的右部A1和A2之前,而不是后面,那么A.in在执行Print(A.in)时已有定义。,S A1in:=1 A1A2 in:=2 A2 A a print(A in) ,27,8.2 中间语言,用于编译程序 源程序经过语义分析被译成中间代码序列 (中间语言的语句) 用中间语言过渡的好处: 便于编译系统的实现、移植、代码优化,28,编译中的语义分析,描述方法 利用属性文法描述如何将各种语句和表达式翻译成中间代码 工作方式 分析与综合并行进行 每识别出一个语言结构时, 完成相应的语义检查与中间代码生成,29,常用的中间

11、语言,三地址代码(四元式) 语法结构树(三元式) 后缀式 特点 形式简单、语义明确、便于翻译 独立于目标语言,30,三元式和树形表示,每个三元式由三个部分组成,分别是:算符op,第一运算对象ARG1和第二运算对象ARG2。运算对象可能是源程序中的变量,也可能是某个三元式的结果,用三元式的编号表示。 表达式的树形表示很容易实现:简单变量或常数的树就是该变量或常数自身,如果表达式e1和e2的树分别为T1和T2,那么e1+e2,e1*e2,e1的树分别为:,+,e1,e2,e1,e2,*,e1,-,31,例 : A + B * ( C - D ) + E / ( C - D ) N三元式:,(1)

12、( - C D ) (2) ( * B (1) ) (3) ( + A (2) ) (4) ( - C D ) (5) ( (4) N ) (6) ( / E (5) ) (7) ( + (3) (6) ),32,例 : A + B * ( C - D ) + E / ( C - D ) N语法结构树:,33,后缀式(逆波兰式),形式:操作数 1,操作数 2,运算符 特点: 操作数之间的相对次序相同 运算符在式中出现的顺序恰为表达式的运算顺序; 每个运算符和在它之前出现且紧靠它的两个操作数构成一个最小表达式;,34,例,a := b * (- c) + b * (- 34)的后缀式:a b c

13、 - * b 34 - * + :=,35,四元式(三地址代码),一般形式 x := y op z 其中 x, y, z 为变量名、常数或编译产生的临时变量 四元式(op, x, y, z) 种类:x := y op z 双目运算x := op y 单目运算x := y 赋值if x relop y goto 条件转移,36,a=b*c+b*d的四元式表示,(1)(*, b, c, t1) (2)(*, b, d, t2) (3)(+, t1, t2, t3) (4)(=,t3, , a)为了更直观,上述四元式序列也可以写成: (1)t1=b*c (2)t2=b*d (3)t3=t1+t2 (

14、4)a=t3,37,其他三地址代码,goto l 无条件转移param x 实在参数call p, n (n是参数个数) 过程调用return x 过程返回x := yi 数组运算 xi := yx := &y 指针运算x := *y*x = y,38,语句的语义翻译基本要求:,充分了解需要翻译语句的语义规则,根据语义,设计语义翻译之后的目标结构(中间代码形式) 根据目标结构,改写文法并设计相应的语义处理子程序(语义规则),必要时需引进一些翻译时要用到的语义变量和语义过程,39,8.3 实现赋值语句的语义翻译,赋值语句的文法Sid:=EEE1+E2EE1*E2E -EE(E1)Eid,t1:=

15、c+dt2:=b*t1a:=t2,40,8.3 实现赋值语句的语义翻译,语义过程 emit,产生一条三地址代码 newtemp,产生新的临时变量,返回变量在临时空间的位置 lookup(id.name),在符号表中查找变量,返回变量在符号表中的位置 属性设置 place,存储位置 ,表示变量在符号表中的位置或者临时变量在存储空间的位置,41,赋值语句三地址代码的语义翻译 Sid:=E p:=lookup(id.name); if pnil then emit(p:= E.place) else error EE1+E2 E.place=newtemp; emit(E.place:=E1.pla

16、ce+E2.place) EE1*E2 E.place=newtemp; emit(E.place:=E1.place*E2.place) E -E E.place:=newtemp;emit(E.place := - E.place,42,(接上页)E(E1) E.place:=E1.place Eid p:=lookup(id.name); if pnil then E.place:=p else error , E.place:=newtemp; emit(E.place:=E1.place),43,例:翻译a:=-c+b*d,44,语法制导翻译过程,因为属性place是综合属性,所以用

17、自底向上的分 析方法来进行语法制导翻译。 (1)E11c ,为简单起见,设lookup(c)=c,E11.place:=c (2)E1 -E11, 首先调用newtemp过程,生成E1的存储位置,假设记为t1,然后调用emit过程,生成三地址语句:t1:=-c (3) E21b , 有E21.place:=b (4) E22d , 有E22.place:=d,45,(5)E2 E21 *E22, 首先调用newtemp过程,生成E2的存储位置,假设记为t2,然后调用emit过程,生成三地址语句:t2:=b*d (6)E E1 +E2, 首先调用newtemp过程,生成E的存储位置,假设记为t3

18、,然后调用emit过程,生成三地址语句:t3:=t1*t2 (7) Sa:=E,调用emit过程,生成三地址语句:a:=t3翻译至此结束,对例题依次做了7次归约,每次 调用相应的子程序,生成三地址代码序列:,46,翻译中的其他问题,运算合法性检查 利用符号表保存的名字类型 类型自动转换 填加专用指令 临时变量空间的统计 了解需求、及时释放,47,8.4 布尔表达式的语义翻译,布尔表达式的文法EE1 or E2 | E1 and E2 | not E1 | true | false | id1 relop id2 布尔表达式的作用 用于计算逻辑值 用于控制语句之中的条件表达式,如if-then,

19、if-then-else和while-do等之中的条件表达式,48,8.4.1 布尔表达式的翻译方法,布尔表达式的表示 方法一:用数值表示真和假,从而对布尔表达 式的求值可以象对算术表达式的求值那样一步 一步地来计算 方法二:通过对程序流的控制,即用程序中控 制转移到达的位置来表示布尔表达式的值,49,8.4.2 数值表示法,用1表示真,0表示假来实现布尔表达式的翻译 布尔表达式:a or b and not c 翻译成三地址代码序列:,t1:=not c t2:=b and t1t3:=a or t2,50,100 : if ab goto l03 101 : t:=0 102 : goto

20、 l04 103 : t:=1,关系表达式: ab 等价于if ab then t:=1 else t:=0 翻译成三地址代码序列:,51,关于布尔表达式的数值表示法的翻译 语义过程 产生中间代码 emit 产生新的临时变量 newtemp 属性设置 存储位置 place,52,关于布尔表达式的数值表示法的翻译模式 EE1 or E2 E.place:=newtemp; emit(E.place:=E1.placeor E2.place) EE1 and E2 E.place:=newtemp; emit(E.place:=E1.placeand E2.place) Enot E1 E.pla

21、ce:=newtemp; emit(E.place:= not E1.place) Etrue E.place:=newtemp; emit(E.place:= 1) Efalse E.place:=newtemp; emit(E.place:= 0),53,(接上页)Eid1 relop id2 E.place:=newtemp; emit(if id1.place relop.op d2.placegoto nextcode+3); emit(E.place:= 0); emit(gotonextcode+2); emit(E.place:= 1),54,8.4.3 控制语句中的布尔表达式

22、的翻译,用程序流向的控制来实现布尔表达式的翻译,作为布尔表达式,最终总会有转向E的真出口E.true和假出口E.false 布尔表达式E:ad 翻译成三地址代码序列,100 if ab goto 一 E.true=100101 goto 一 E.false=101,55,使用回填翻译控制语句中的布尔表达式 (1)EE1 or E2 (ad)(2) E E1 and E2 (ad),E1.code,E2.code,E1.false:,to E1.true,to E1.false,to E2.true,to E2.false,E1.code,E2.code,E1.true:,to E1.true,

23、to E1.false,to E2.true,to E2.false,to E.true,to E.false,to E.true,to E.false,56,使用回填翻译控制语句中的布尔表达式 (3) E not E1 (not ab)(4) E(E1) ( (ab),57,使用回填翻译控制语句中的布尔表达式 (5) E id1 relop id2 (ab)(6) E true (7) E false,58,使用回填翻译控制语句中的布尔表达式 拉链: .L1: goto L;.L2: goto L;.L3: goto L;.L: . 回填:,L2,L1,0,当翻译进行到能确定转向点时,从链

24、表表头出发沿着链点一一回填真正的转向点。,59,翻译模式用到如下两个函数:1merge(p1,p2):连接由指针p1和p2指 向的两条链并且返回一个指向连接后的链表 表首的指针。 2backpatch ( p,i ) :把i作为目标标号 回填到p所指向的表中的每一个转移指令中去。此处的“表”都是为“反填”所拉的链,60,依次分析,得到如下四元式:100 : if ab goto- 101 : goto- 102 :if cd goto- 103 : goto- 104 : if ef goto- 105 : goto-,经过回填得到:100 : if ab goto 0101 : goto l

25、02 102 : if cd goto l04 103 : goto 0104 : if ef goto 100 105 : goto 103,E.True的链首为104,E.false的链首为105 当确定了真和假的出口,就可以进行回填,表达式:af的翻译,61,8.5 控制结构的翻译,高级语言的控制结构 顺序 begin 语句; 语句 end 条件 if_then_else if_thenswitch case 循环 while_do do_while for repeat_until 三地址代码的控制结构 goto l if x relop y goto l,62,简单布尔表达式的翻译,

26、E T1 relop T2 E.code := gen( if T1.placerelop.op T2.place gotoE.true ) | gen( gotoE.false ) T id T.place := id.entry T num T.place := num.val,63,S if E then S1 else S2 的翻译,代码序列 E S1 S2 属性关系 S1.begin = E.true S2.begin = E.false S1.next = S2.next = S.next,64,If 语句的属性文法,S if E then S1 E.true := newlabe

27、l; else S2 E.false := newlabel;S1.next := S2.next := S.next;S.code := E.code | gen( E.true: ) |S1.code | gen( goto S.next ) |gen( E.false: ) | S2.code,65,S while E do S1 的翻译,属性设置(继承) 布尔式 E 代码段真出口 true 代码段假出口 false 语句 S 代码段的入口 begin 后续段入口 next,66,While 语句的属性文法,S while E do S1 E.false := S.next;E.true

28、 := S1.begin := newlabel;S.begin := S1.next := newlabel;S.code := gen( S.begin: ) | E.code |gen( E.true: ) | S1.code |gen( gotoS.begin ) 语义过程 新标号的产生 newlabel,67,例 8-10 翻译下列语句,while a y do z := x + 1;elsex := y,68,生成的三地址代码序列,L1: if a y goto L5;goto L1; L5: z := x + 1;goto L3; L4: x := y;goto L1; Lnex

29、t:,E.code,E1.code,S11.code,S12.code,S1.code,69,思考:For 语句的翻译,FOR := TO DO FOR := DOWNTO DO 其中,语句的循环变量的步长为1,语句的循环变量的步长为-1。,70,8.6 过程(函数)调用语句,语法: call id(Elist) 语义: 建立形式参数和实在参数的对应关系后,执行被调用过程的过程体。,71,过程语句的执行,为被调用者的活动记录分配存储区域 计算过程调用中各个实在参数的值,并把值存放在到相应的位置。 设置环境指针(访问链)等,使得被调用过程可以访问外围数据。 保护交用过程的机器状态,包括寄存器状态

30、。 初始化被调用过程的局部数据。 控制转移到被调用过程的入口处。,72,目标代码设计,过程调用入口和出口部分的处理可以调用入口子程序和出口子程序来完成。 代码模式如下: 计算实在参数p1的值的代码 param p1 计算实在参数pn的值的代码 param pm call P m,73,参数的传递,值调用 值参数的形式参数被当作过程的局部变量看待,存储区域在被调用者的活动记录中。 调用者计算实在参数的值,并把该值送入相应位置。 引用调用 如果参数是变量,传送给形式参数的实际上是参数的地址。 如果参数是常量或者表达式,首先给这些值分配临时存储区域,然后把这个区域的地址传送给被调用者。 在被调用的过

31、程中,对于参数的使用通过间接的方式实现。比如swap(x,y)中,x,y为引用调用时,x=1的操作为向x中的值存放,74,8.7 说明部分的分析与处理,对每个过程说明的对象(变量,常量和过程)造名字表 填写标识符的所在层次、属性和分配的相对位置。标识符的属性不同时,所需填入的信息也不同。登录信息由ENTER过程完成。,75,说明部分的分析与处理(程序),说明类型的定义:object= (constant, variable,procedur)(定义纯量/枚举类型) 名字表的定义table:array0txmax of recordname:alfa;case kind:object ofcon

32、stant:(val:integer);variable:procedur:(level,adr,size : integer);,76,例程序说明部分为: CONST A=35,B=49; VAR C,D,E; PROCEDURE P; VAR G ;,名字 类型 层次/值 地址 存储空间,Const(常量)无层次,对应名字表,77,8.8 数组说明的翻译,空间分配 首地址、空间尺寸 表格管理 维数、下标上界、下标下界 存放方式 按行存放、按列存放,78,数组元素的引用,数组元素的翻译 完成上下界检查 生成代码完成参照相对地址的计算 目标 x := yi 和 xi := y i 是相对地址,不是数组下标,

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

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

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


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

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

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