欢迎来到三一办公! | 帮助中心 三一办公31ppt.com(应用文档模板下载平台)
三一办公
全部分类
  • 办公文档>
  • PPT模板>
  • 建筑/施工/环境>
  • 毕业设计>
  • 工程图纸>
  • 教育教学>
  • 素材源码>
  • 生活休闲>
  • 临时分类>
  • ImageVerifierCode 换一换
    首页 三一办公 > 资源分类 > PPT文档下载  

    编译原理课件第7章.ppt

    • 资源ID:6599857       资源大小:848.50KB        全文页数:114页
    • 资源格式: PPT        下载积分:15金币
    快捷下载 游客一键下载
    会员登录下载
    三方登录下载: 微信开放平台登录 QQ登录  
    下载资源需要15金币
    邮箱/手机:
    温馨提示:
    用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)
    支付方式: 支付宝    微信支付   
    验证码:   换一换

    加入VIP免费专享
     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    编译原理课件第7章.ppt

    2023/11/16,1,第7章语义分析与中间代码生成,7.1 中间代码的形式7.2 声明语句的翻译7.3 赋值语句的翻译7.4 类型检查7.5 控制结构的翻译7.6 回填7.7 switch语句的翻译7.8 过程调用和返回语句的翻译7.9 输入输出语句的翻译7.10 本章小结,2023/11/16,2,7.1 中间代码的形式,中间代码的作用过渡:经过语义分析被译成中间代码序列中间代码的形式中间语言的语句中间代码的优点形式简单、语义明确、独立于目标语言便于编译系统的实现、移植、代码优化常用的中间代码语法树节)逆波兰表示、三地址码(三元式和四元式)、DAG图表示,2023/11/16,3,7.1.1 逆波兰表示,中缀表达式的计算顺序不是运算符出现的自然顺序,而是根据运算符间的优先关系来确定的,因此,从中缀表达式直接生成目标代码一般比较麻烦。波兰逻辑学家J.Lukasiewicz于1929年提出了后缀表示法,其优点为:表达式的运算顺序就是运算符出现的顺序,它不需要使用括号来指示运算顺序。,2023/11/16,4,7.1.1 逆波兰表示,例7.1 下面给出的是一些表达式的中缀、前缀和后缀表示。中缀表示前缀表示后缀表示a+b+abab+a*(b+c)*a+bcabc+*(a+b)*(c+d)*+ab+cd ab+cd+*a:=a*b+c*d:=a+*ab*cd abc*bd*+:=,2023/11/16,5,7.1.2 三地址码,所谓三地址码,是指这种代码的每条指令最多只能包含三个地址,即两个操作数地址和一个结果地址。如x+y*z三地址码为:t1:=y*z t2:=x+t1三地址码中地址的形式:名字、常量、编译器生成的临时变量。,2023/11/16,6,7.1.2 三地址码,例7.2 赋值语句a:=(-b)*(c+d)-(c+d)的三地址码如图7.1所示,t1:=minus bt2:=c+dt3:=t1*t2t4:=c+dt5:=t3-t4a:=t5,图7.1 a:=(-b)*(c+d)-(c+d)的三地址码,2023/11/16,7,7.1.2 三地址码,1形如x:=y op z的赋值指令;2形如x:=op y的赋值指令;3形如 x:=y的复制指令;4无条件跳转指令goto L;5形如 if x goto L(或if false x goto L)的条件跳转指令;6形如if x relop y goto L的条件跳转指令;7过程调用和返回使用如下的指令来实现:param x用来指明参数;call p,n和y=call p,n用来表示过程调用和函数调用;return y表示过程返回;8形如x:=yi和xi:=y的变址复制指令;9形如x:=&y、x:=*y和*x:=y的地址和指针赋值指令。,2023/11/16,8,四元式,四元式是一种比较常用的中间代码形式,它由四个域组成,分别称为op、arg1、arg2和result。op是一个一元或二元运算符,arg1和arg2分别是op的两个运算对象,它们可以是变量、常量或编译器生成的临时变量,运算结果则放入result中。,图7.2(a)图7.1中三地址码的四元式表示,2023/11/16,9,三元式,为了节省临时变量的开销,有时也可以使用只有三个域的三元式来表示三地址码。三元式的三个域分别称为op,arg1和arg2,op,arg1和arg2的含义与四元式类似,区别只是arg1和arg2可以是某个三元式的编号(图7.2(b)中用圆括号括起来的数字),表示用该三元式的运算结果作为运算对象。,图7.2(b)图7.1中三地址码的三元式表示,2023/11/16,10,7.1.3 图表示,类似于表达式的抽象语法树一样,在dag(directed acyclic graph)中,每个节点对应一个运算符,代表表达式的一个子表达式,其子节点则与该运算符的运算对象相对应,叶节点对应的是变量或者常量,可以看成是原子运算。利用dag可以很容易地消除公共子表达式例7.3 表达式a+a*(b-c)-(b-c)/d的dag如图7.5所示。,图7.5 a+a*(b-c)-(b-c)/d的dag图,对应的三地址码:t1:=b-ct2:=a*t1t3:=a+t2t4:=t1/dt5:=t3-t4,2023/11/16,11,生成dag的语法制导定义,2023/11/16,12,7.2 声明语句的翻译,声明语句的作用为程序中用到的变量或常量名指定类型 类型的作用 类型检查:类型检查的任务是验证程序运行时的行为是否遵守语言的类型的规定,也就是是否符合该语言关于类型的相关规则。辅助翻译:编译器从名字的类型可以确定该名字在运行时所需要的存储空间。在计算数组引用的地址、加入显式的类型转换、选择正确版本的算术运算符以及其它一些翻译工作时同样需要用到类型信息。编译的任务在符号表中记录被说明对象的属性(种别、类型、相对地址、作用域等),为执行做准备,2023/11/16,13,7.2.1 类型表达式,类型可以具有一定的层次结构,因此用类型表达式来表示。类型表达式的定义如下:1基本类型是类型表达式。典型的基本类型包括boolean、char、integer、real及void等。2类型名是类型表达式。3将类型构造符array应用于数字和类型表达式所形成的表达式是类型表达式。如果T是类型表达式,那么array(I,T)就是元素类型为T、下标集为I的数组类型表达式。4如果T1和T2是类型表达式,则其笛卡尔乘积T1T2也是类型表达式。,2023/11/16,14,7.2.1 类型表达式,5类型构造符record作用于由域名和域类型所形成的表达式也是类型表达式。记录record是一种带有命名域的数据结构,可以用来构成类型表达式。例如,下面是一段Pascal程序段:type row=record address:integer;lexeme:array1.15 of char end;var table:array 1.10 of row;6如果T是类型表达式,那么pointer(T)也是类型表达式,表示“指向类型为T的对象的指针”。7类型表达式可以包含其值为类型表达式的变量。,2023/11/16,15,7.2.2 类型等价,许多类型检查的规则都具有如下的形式:if两个类型表达式等价then返回一种特定类型else返回type_error。如果用图来表示类型表达式,当且仅当下列条件之一成立时,称两个类型T1和T2是结构等价的:T1和T2是相同的基本类型;T1和T2是将同一类型构造符应用于结构等价的类型上形成的;T1是表示T2的类型名。如果将类型名看作只代表它们自己的话,则上述条件中的前两个将导致类型表达式的名字等价两个类型表达式名字等价当且仅当它们完全相同,2023/11/16,16,7.2.3 声明语句的文法,P prog id(input,output)D;SD D;D|List:T|proc id D;SList List1,id|idT integer|real|array C of T1|T1|record DC num C|D 程序说明部分的语法变量S 程序体部分的语法变量T 类型的语法变量,需要表示成类型表达式C 数组下标的语法变量,2023/11/16,17,语义属性、辅助过程与全局变量的设置,文法变量T(类型)的语义属性type:类型(表达式)width:类型所占用的字节数辅助子程序enter:将变量的类型和地址填入符号表中array:数组类型处理子程序全局变量offset:已分配空间字节数,用于计算相对地址,2023/11/16,18,7.2.4 过程内声明语句的翻译,声明语句的主要作用是为名字指定类型,从名字的类型可以确定它在运行时所需要的存储空间。数据对象的存储安排与目标机器的寻址方式有关。对声明语句的限制也影响数据对象的存储安排,2023/11/16,19,声明语句的翻译模式,P offset:=0 DDD;DDid:T enter(id.name,T.type,offset);offset:=offset+T.widthTinteger T.type:=integer;T.width:=4Treal T.type:=real;T.width:=8Tarray num of T1 T.type:=array(num.val,T1.type);T.width:=num.val*T1.widthTT1 T.type:=pointer(T1.type);T.width:=4,PMDM offset:=0,2023/11/16,20,例 x:real;i:integer 的翻译,enter(x,real,0),offset=0,offset=8,T.type=realT.width=8,offset=12,T.type=integerT.width=4,enter(i,integer,8),Did:T enter(id.name,T.type,offset);offset:=offset+T.width,2023/11/16,21,例 x:real;i:integer 的翻译,Poffset:=0Doffset:=0D;Doffset:=0 x:Tenter(x,T.type,offset);offset:=offset+T.width;Doffset:=0 x:realT.type:=real;T.width:=8 enter(x,T.type,offset);offset:=offset+T.width;Dx:real(x,real,0);offset:=8;Dx:real(x,real,0);offset:=8;i:T enter(id.name,T.type,offset);offset:=offset+T.widthx:real(x,real,0);offset:=8;i:integerT.type:=integer;T.width:=4enter(i,T.type,offset);offset:=offset+T.widthx:real(x,real,0);i:integer(i,integer,8);offset:=12,2023/11/16,22,7.2.5 嵌套过程中声明语句的翻译,所讨论语言的文法P prog id(input,output)D;S D D;D|id:T|proc id D;S 语义动作用到的函数mktable(previous):创建一个新的符号表;enter(table,name,type,offset)addwidth(table,width):符号表的大小;enterproc(table,name,newtable)在table指向的符号表中为name建立一个新表项;,2023/11/16,23,P prog id(input,output)M D;S addwidth(top(tblptr),top(offset);pop(tblptr);pop(offset)M t:=mktable(nil);push(t,tblptr);push(0,offset)D D1;D2D proc id;N D1;S t:=top(tblptr);addwidth(t,top(offset);pop(tblptr);pop(offset);enterproc(top(tblptr),id.name,t)Did:T enter(top(tblptr),id.name,T.type,top(offset);top(offset):=top(offset)+T.widthN t:=mktable(top(tblptr);push(t,tblptr);push(0,offset),7.2.5 嵌套过程中声明语句的翻译,2023/11/16,24,program sort(input,output);var a:array0.10 of integer;x:integer;procedure readarray;var i:integer;begin aend;procedure exchange(i,j:integer);begin x:=ai;ai:=aj;aj:=x;end;procedure quicksort(m,n:integer);var k,v:integer;function partition(y,z:integer):integer;var i,j:integer;begin a v exchange(i,j)end;begin end;begin end;,例 一个带有嵌套的pascal程序(图7.11),2023/11/16,25,表 头,空,sort,offset,tblptr,top,top,0,2023/11/16,26,表 头,空,sort,offset,tblptr,top,top,40,a array 0,2023/11/16,27,x integer 40,a array 0,表 头,空,sort,offset,tblptr,top,top,44,2023/11/16,28,表 头,空,sort,readarrary,表 头,offset,tblptr,top,top,44,0,a array 0,x integer 40,2023/11/16,29,表 头,空,sort,readarrary,表 头,offset,tblptr,top,top,44,4,a array 0,x integer 40,i integer 0,2023/11/16,30,表 头,空,sort,readarrary,表 头 4,offset,tblptr,top,top,44,a array 0,x integer 40,i integer 0,readarray,指向readarray,2023/11/16,31,表 头,空,sort,readarrary,表 头 4,offset,tblptr,44,a array 0,x integer 40,i integer 0,readarray,指向readarray,exchange,表 头,top,top,0,2023/11/16,32,表 头,空,sort,readarrary,表 头 4,offset,tblptr,44,a array 0,x integer 40,i integer 0,readarray,指向readarray,exchange,表 头 0,top,top,exchange,指向exchange,2023/11/16,33,表 头,空,sort,readarrary,表 头 4,offset,tblptr,44,a array 0,x integer 40,i integer 0,readarray,指向readarray,exchange,表 头 0,top,top,exchange,指向exchange,表 头,quicksort,0,2023/11/16,34,表 头,空,sort,readarrary,表 头 4,offset,tblptr,44,a array 0,x integer 40,i integer 0,readarray,指向readarray,exchange,表 头 0,top,top,exchange,指向exchange,表 头,quicksort,4,k integer 0,2023/11/16,35,表 头,空,sort,readarrary,表 头 4,offset,tblptr,44,a array 0,x integer 40,i integer 0,readarray,指向readarray,exchange,表 头 0,top,top,exchange,指向exchange,表 头,quicksort,8,k integer 0,v integer 4,2023/11/16,36,表 头,空,sort,readarrary,表 头 4,offset,tblptr,44,a array 0,x integer 40,i integer 0,readarray,指向readarray,exchange,表 头 0,top,top,exchange,指向exchange,表 头,quicksort,8,k integer 0,v integer 4,表 头,partition,0,2023/11/16,37,表 头,空,sort,readarrary,表 头 4,offset,tblptr,44,a array 0,x integer 40,i integer 0,readarray,指向readarray,exchange,表 头 0,top,top,exchange,指向exchange,表 头,quicksort,8,k integer 0,v integer 4,表 头,partition,4,i integer 0,2023/11/16,38,表 头,空,sort,readarrary,表 头 4,offset,tblptr,44,a array 0,x integer 40,i integer 0,readarray,指向readarray,exchange,表 头 0,top,top,exchange,指向exchange,表 头,quicksort,8,k integer 0,v integer 4,表 头,partition,8,i integer 0,j integer 4,2023/11/16,39,表 头,空,sort,readarrary,表 头 4,offset,tblptr,44,a array 0,x integer 40,i integer 0,readarray,指向readarray,exchange,表 头 0,top,top,exchange,指向exchange,表 头,quicksort,8,k integer 0,v integer 4,表 头 8,partition,i integer 0,j integer 4,partition,2023/11/16,40,表 头,空,sort,readarrary,表 头 4,offset,tblptr,44,a array 0,x integer 40,i integer 0,readarray,指向readarray,exchange,表 头 0,top,top,exchange,指向exchange,表 头 8,quicksort,k integer 0,v integer 4,表 头 8,partition,i integer 0,j integer 4,partition,quicksort,2023/11/16,41,表 头 44,空,sort,readarrary,表 头 4,offset,tblptr,a array 0,x integer 40,i integer 0,readarray,指向readarray,exchange,表 头 0,top,top,exchange,指向exchange,表 头 8,quicksort,k integer 0,v integer 4,表 头 8,partition,i integer 0,j integer 4,partition,quicksort,2023/11/16,42,7.2.6 记录的翻译,空间分配设置首地址和各元素的相对地址大于所需的空间(对齐)例:struct Node float x,y;struct node*next;node;,0,4,8,2023/11/16,43,7.2.6 记录的翻译,符号表及有关表格处理为每个记录类型单独构造一张符号表将域名id的信息(名字、类型、字节数)填入到该记录的符号表中所有域都处理完后,offset将保存记录中所有数据对象的宽度总和T.type通过将类型构造器record应用于指向该记录符号表的指针获得,2023/11/16,44,7.2.6 记录的翻译,T record D endT record L D endT.type:=record(top(tblptr);T.width:=top(offset);pop(tblptr);pop(offset)L t:=mktable(nil);push(t,tblprt);push(0,offset),2023/11/16,45,7.3 赋值语句的翻译,翻译的需求充分了解各种语言现象的语义包括:控制结构、数据结构、单词充分了解它们的实现方法目标语言的语义了解中间代码的语义了解运行环境,2023/11/16,46,辅助子程序与语义属性设置,辅助子程序gencode(code),emit(code):产生一条中间代码newtemp:产生新的临时变量lookup:检查符号表中是否出现某名字语义属性设置中间代码序列:code地址:addr下一条四元式序号:nextquad,2023/11/16,47,7.3.1 简单赋值语句的翻译,S id:=E p:=lookup(id.name);if p nil thengencode(p,:=,E.addr)else error E E1+E2E.addr:=newtemp;emit(E.addr,:=,E1.addr,+,E2.addr)E E1 E.addr:=newtemp;emit(E.addr,:=,uminus,E1.addr)E(E1)E.addr:=E1.addr E id p:=lookup(id.name);if p nil then E.addr:=p else error,2023/11/16,48,基于临时变量生存期特征的三地址代码,x:=-a b+c,2023/11/16,49,C赋值语句翻译举例,#include int main()int a,b,c,d,e;scanf(%d,%d,%d,%d,2023/11/16,50,7.3.2 数组元素的寻址,数组元素引用的翻译完成上下界检查生成完成相对地址计算的代码目标x:=yi 和 yi:=xy为数组地址的固定部分相当于第1个元素的地址,i是相对地址,不是数组下标,数组说明的翻译符号表及有关表格(内情向量)的处理维数、下标上界、下标下界、类型等首地址、需用空间计算按行存放、按列存放影响具体元素地址的计算,2023/11/16,51,数组元素地址计算行优先,一维数组Alow1:up1(nk=upk-lowk+1)addr(Ai)=base+(i-low1)*w=(base-low1*w)+i*w=c+i*w二维数组Alow1:up1,low2:up2;Ai1,i2addr(Ai1,i2)=base+(i1-low1)*n2+(i2-low2)*w=base+(i1-low1)*n2*w+(i2-low2)*w=base-low1*n2*w-low2*w+i1*n2*w+i2*w=base-(low1*n2-low2)*w+(i1*n2+i2)*w=c+(i1*n2+i2)*w,A1,1,A1,2,A1,3 A2,1,A2,2,A2,3,2023/11/16,52,C数组举例,#include int main()int a1020,i,j;for(i=0;i10;i+)for(j=0;j20;j+)aij=1;return 1;,2023/11/16,53,7.4 类型检查,类型检查具有发现程序错误的能力,为了进行类型检查,编译程序需要为源程序的每个语法成分赋予一个类型表达式,名字的类型表达式保存在符号表中,其他语法成分(如表达式E或语句S)的类型表达式则作为文法符号的属性保存在语义栈中。类型检查的任务就是确定这些类型表达式是否符合一定的规则,这些规则的集合通常称为源程序的类型系统,2023/11/16,54,x:=y+i j(x和y的类型是real,i和j的类型是integer)中间代码t1:=i int jt2:=inttoreal t1 t3:=y real+t2 x:=t3,2023/11/16,55,E E1+E2的语义子程序E.addr:=newtempif E1.type=integer and E2.type=integer then begin gencode(E.addr,:=,E1.addr,int+,E2.addr);E.type=integerendelse if E1.type=integer and E2.type=real then beginu:=newtemp;gencode(u,:=,inttoreal,E1.addr);gencode(E.addr,:=,u,real+,E2.addr);E.type:=realend.,2023/11/16,56,7.5 控制结构的翻译,高级语言的控制结构顺序结构 begin 语句;;语句end分支结构 if_then_else、if_thenswitch、case循环结构 while_do、do_while for、repeat_untilgoto语句三地址码goto n(j,_,_,n)if x relop y goto n(jrelop,x,y,n),2023/11/16,57,7.5.1 布尔表达式的翻译,基本文法B B1 or B2|B1 and B2|not B1|(B1)|E1 relop E2|true|false处理方式数值表示法(与算术表达式的处理类似)真:B.addr=1假:B.addr=0真假出口表示法(作为其他语句的条件改变控制流程,隐含着程序中的位置)真出口:B.true假出口:B.false,2023/11/16,58,7.5.1 布尔表达式的翻译,a or b and not ct1:=not ct2:=b and t1t3:=a or t2ab100:if ab goto 103101:t:=0102:goto 104103:t:=1104,2023/11/16,59,TC中对于ab的处理,源代码:(BoolTC.c)#include main()int a,b,c;scanf(%d,%d,汇编代码:movax,word ptr bp-4cmpax,word ptr bp-2jge3movsi,1jmpshort 23:xorsi,si2:pushsi;si存放最后结果,2023/11/16,60,Turbo C中栈的处理,高位地址,低位地址,SP,BP,定义变量后,先定义的变量在栈顶(低位地址),后定义的变量在栈顶(高位地址)注:不适用VC中栈的处理。,2023/11/16,61,用数值表示布尔值的翻译,nextquad是下一条三地址码指令的序号,每生成一条三地址码指令gencode便会将nextquad加1 B B1 or B2 B.addr:=newtemp;gencode(B.addr:=B1.addrorB2.addr)B B1 and B2 B.addr:=newtemp;gencode(B.addr:=B1.addrandB2.addr)B not B1 B.addr:=newtemp;gencode(B.addr:=notB1.addr),2023/11/16,62,用数值表示布尔值的翻译,B(B1)B.addr:=B1.addr B E1 relop E2 B.addr:=newtemp;gencode(ifE1.addr relop.op E2.addrgotonextquad+3);gencode(B.addr:=0);gencode(gotonextquad+2);gencode(B.addr:=1)B true B.addr:=newtemp;gencode(B.addr:=1)B false B.addr:=newtemp;gencode(B.addr:=0),2023/11/16,63,例7.8 对ab or cd and ef的翻译,100:if ab goto 103 107:t2:=1101:t1:=0 108:if ef goto 111102:goto 104 109:t3:=0103:t1:=1 110:goto 112104:if cd goto 107 111:t3:=1105:t2:=0 112:t4:=t2 and t3106:goto 100 113:t5:=t1 or t4,2023/11/16,64,7.5.2 常见控制结构的翻译,文法S if B then S1S if B then S1 else S2S while B do S1S begin Slist endSlist Slist;S|SB是控制结构中的布尔表达式函数newlabel返回一个新的语句标号属性B.true和B.false分别用于保存B为真和假时控制流要转向的语句标号,2023/11/16,65,7.5.2 常见控制结构的翻译,翻译S时允许控制从S.code中跳转到紧接在S.code之后的那条三地址码指令,但在某些情况下,紧跟S.code的指令是跳转到某个标号L的跳转指令,用继承属性S.next可以避免从S.code中跳转到一条跳转指令这样的连续跳转。S.next的值是一个语句标号,它是S的代码执行后应执行的第一个三地址码指令的标号。while语句中用S.begin保存语句的开始位置,2023/11/16,66,7.5.2 常见控制结构的翻译,B.false:,B.false:,2023/11/16,67,7.5.2 常见控制结构的翻译,S if B then S1B.true:=newlabel;B.false:=S.next;S1.next:=S.next;S.code:=B.code|gencode(B.true,:)|S1.code,2023/11/16,68,7.5.2 常见控制结构的翻译,S if B then S1 else S2B.true:=newlabel;B.false:=newlabel;S1.next:=S.next;S2.next:=S.next;S.code:=B.code|gencode(B.true,:)|S1.code|gencode(goto,S.next)|gen(B.false,:)|S2.code,2023/11/16,69,7.5.2 常见控制结构的翻译,S while B do S1 S.begin:=newlabel;B.true:=newlabel;B.false:=S.next;S1.next:=S.begin;S.code:=gencode(S.begin,:)|B.code|gencode(B.true,:)|S1.code|gencode(goto,S.begin),2023/11/16,70,7.5.2 常见控制结构的翻译,S S1;S2S1.next:=newlabel;S2.next:=S.next;S.code:=S1.code|gencode(S1.next,:)|S2.code,2023/11/16,71,TC2中对于ifthen的处理,源代码(IfTC.c):#include main()int a,b,e=0;scanf(%d,%d,汇编代码:xorsi,simovax,word ptr bp-4cmpax,word ptr bp-2jge2movsi,12:pushsi;si存放最后结果,2023/11/16,72,TC2中对于if.then.else的处理,源代码(IfElseTC.c):#include main()int a,b,e;scanf(%d,%d,汇编代码:movax,word ptr bp-4cmpax,word ptr bp-2jge2movsi,1jmpshort 32:movsi,23:pushsi;si存放最后结果,2023/11/16,73,TC2中对于while循环的处理,源代码(WhileTC.c):#include main()int a,b;scanf(%d,%d,汇编代码:jmpshort 24:incword ptr bp-42:movax,word ptr bp-4cmpax,word ptr bp-2jl43:pushword ptr bp-4;bp-4存放最后结果,2023/11/16,74,7.5.3 布尔表达式的控制流翻译,属性(继承属性)B.true,B为真时控制到达的位置;B.false,B为假时控制到达的位置。abif ab goto B.truegoto B.falseBB1 or B2如果B1为真,则立即可知B为真,即B1.true与B.true相同;如果B1为假,则必须计算B2的值,令B1.false为B2的开始B2的真假出口分别与B的真假出口相同,2023/11/16,75,简单布尔表达式的翻译示例 例7.9 ab or cd and ef,if ab goto Ltrue goto L1L1:if cd goto L2 goto LfalseL2:if ef goto Ltrue goto Lfalse,2023/11/16,76,7.5.3 布尔表达式的控制流翻译,B B1 or B2 B1.true:=B.true;B1.false:=newlabel;B2.true=B.true;B2.false:=B.false;B.code:=B1.code|gencode(B1.false:)|B2.code B B1 and B2 B1.true:=newlabel;B1.false:=B.false;B2.true=B.true;B2.false:=B.false;B.code:=B1.code|gencode(B1.true:)|B2.code B not B1 B1.true:=B.false;B1.false:=B.true;B.code:=B1.code,2023/11/16,77,7.5.3 布尔表达式的控制流翻译,B(B1)B1.true:=B.true;B1.false:=B.false;B.code:=B1.codeB E1 relop E2 B.code:=gencode(ifE1.addr relop E2.addrgotoB.true);|gencode(goto B.false)B true B.code:=gencode(goto B.true)B false B.code:=gencode(goto B.false),2023/11/16,78,例7.10:翻译下列语句,while a b do B1 if c d thenB2S1 x:=y+z elseS2 x:=y-z,S3,2023/11/16,79,生成的三地址代码序列,L1:if a b goto L2 goto LnextL2:if c d goto L3 goto L4L3:t1:=y+z x:=t1 goto L1L4:t2:=y-z x:=t2 goto L1Lnext:,B1.code,B2.code,S1.code,S2.code,S3.code,while ab do if cd then x:=y+z else x:=y-z,2023/11/16,80,7.6 回填,一遍扫描问题:生成跳转语句时可能不知道要转向指令的标号 先产生暂时没有填写目标标号的转移指令 对于每一条这样的指令作适当的记录,建一个链表 一旦确定了目标标号,再将它“回填”到相应的指令中E.truelistE.falselist,2023/11/16,81,回填,翻译模式用到如下三个函数:1makelist(i):创建一个只包含i的新表,i 是四元式数组的一个索引(下标),或者说 i是四元式代码序列的一个标号。2merge(p1,p2):合并由指针p1和p2指向 的两个表并且返回一个指向合并后的表的 指针。3backpatch(p,i):把i作为目标标号回填到 p所指向

    注意事项

    本文(编译原理课件第7章.ppt)为本站会员(牧羊曲112)主动上传,三一办公仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知三一办公(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    备案号:宁ICP备20000045号-2

    经营许可证:宁B2-20210002

    宁公网安备 64010402000987号

    三一办公
    收起
    展开