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

    编译原理课件07-语义分析和中间代码产生.ppt

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

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

    编译原理课件07-语义分析和中间代码产生.ppt

    第七章 语义分析和中间代码产生,静态语义检查类型检查控制流检查一致性检查 相关名字检查名字的作用域分析,语法分析器,中间代码产生器,静态检查器,中间代码,优化器,中间语言(复杂性界于源语言和目标语言之间)的好处:便于进行与机器无关的代码优化工作 易于移植使编译程序的结构在逻辑上更为简单明确,源语言程序,目标语言程序,中间语言程序,常用的中间语言:后缀式,逆波兰表示三地址代码三元式四元式间接三元式DAG图表示,7.1 中间语言,7.1.1 后缀式,后缀式表示法:Lukasiewicz发明的一种表示表达式的方法,又称逆波兰表示法。一个表达式E的后缀形式可以如下定义:1.如果E是一个变量或常量,则E的后缀式是E自身。2.如果E是E1 op E2形式的表达式,其中op是任何二元操作符,则E的后缀式为E1 E2 op,其中E1 和E2 分别为E1 和E2的后缀式。3.如果E是(E1)形式的表达式,则E1 的后缀式就是E的后缀式。,逆波兰表示法不用括号。只要知道每个算符的目数,对于后缀式,不论从哪一端进行扫描,都能对它进行唯一分解。后缀式的计算用一个栈实现。一般的计算过程是:自左至右扫描后缀式,每碰到运算量就把它推进栈。每碰到k目运算符就把它作用于栈顶的k个项,并用运算结果代替这k个项。,把表达式翻译成后缀式的语义规则描述,产生式EE(1)op E(2)E(E(1)Eid,语义动作E.code:=E(1).code|E(2).code|opE.code:=E(1).codeE.code:=id,E.code表示E后缀形式op表示任意二元操作符“|”表示后缀形式的连接。,数组POST存放后缀式:k为下标,初值为1上述语义动作可实现为:产生式程序段EE(1)op E(2)POSTk:=op;k:=k+1E(E(1)EiPOSTk:=i;k:=k+1例:输入串a+b+c的分析和翻译POST:1 2 3 4 5,7.1.2 图表示法,图表示法DAG抽象语法树,7.1.2 图表示法,无循环有向图(Directed Acyclic Graph,简称DAG)对表达式中的每个子表达式,DAG中都有一个结点一个内部结点代表一个操作符,它的孩子代表操作数在一个DAG中代表公共子表达式的结点具有多个父结点,a:=b*(-c)+b*(-c)的图表示法,产生赋值语句抽象语法树的属性文法,产 生 式语义规则Sid:=ES.nptr:=mknode(assign,mkleaf(id,id.place),E.nptr)EE1+E2E.nptr:=mknode(+,E1.nptr,E2.nptr)EE1*E2E.nptr:=mknode(*,E1.nptr,E2.nptr)E-E1 E.nptr:=mknode(uminus,E1.nptr)E(E1)E.nptr:=E1.nptrEid E.nptr:=mkleaf(id,id.place),7.1.3 三地址代码,三地址代码x:=y op z 表达式x+y z翻译成的三地址语句序列是 t1:=y z t2:=x+t1 出于语句的右边只有一个算符的考虑三地址代码可以看成是抽象语法树或DAG的一种线性表示,三地址代码是语法树或dag的一种线性表示a:=(b+cd)+cd语法树的代码dag的代码t1:=bt2:=c dt3:=t1+t2t4:=c dt5:=t3+t4 a:=t5 新增加的名字对应树/图中的内部结点,三地址代码是语法树或dag的一种线性表示a:=(b+cd)+cd语法树的代码dag的代码t1:=bt2:=c dt3:=t1+t2t4:=t3+t2a:=t4 新增加的名字对应树/图中的内部结点,三地址语句的种类,本书常用的三地址语句赋值语句x:=y op z;x:=op y;x:=y无条件转移goto L条件转移if x relop y goto L过程调用param x 和call p,n过程返回 return y索引赋值x:=yi和 xi:=y地址和指针赋值x:=&y,x:=y和x:=y,生成三地址代码时,临时变量的名字对应抽象语法树的内部结点id:=E对表达式E求值并置于变量T中值id.place:=T,从赋值语句生成三地址代码的S-属性文法,非终结符号S有综合属性S.code,它代表赋值语句S的三地址代码。非终结符号E有如下两个属性:E.place表示存放E值的名字。E.code表示对E求值的三地址语句序列。函数newtemp的功能是,每次调用它时,将返回一个不同临时变量名字,如T1,T2,。,为赋值语句生成三地址代码的S-属性文法定义,产生式语义规则Sid:=ES.code:=E.code|gen(id.place:=E.place)EE1+E2E.place:=newtemp;E.code:=E1.code|E2.code|gen(E.place:=E1.place+E2.place)EE1*E2E.place:=newtemp;E.code:=E1.code|E2.code|gen(E.place:=E1.place*E2.place)E-E1E.place:=newtemp;E.code:=E1.code|gen(E.place:=uminus E1.place)E(E1)E.place:=E1.place;E.code:=E1.codeEid E.place:=id.place;E.code=,三地址语句,三地址语句可看成中间代码的一种抽象形式.编译程序中,三地址代码语句的具体实现可用记录表示.通常有三种表示方法:四元式、三元式、间接三元式。四元式一个带有四个域的记录结构,这四个域分别称为op,arg1,arg2及resultoparg1arg2result(0)uminuscT1(1)*bT1T2(2)uminuscT3(3)*bT3T4(4)+T2T4T5(5):=T5a,三地址语句,三元式 通过计算临时变量值的语句的位置来引用这个临时变量三个域:op、arg1和arg2oparg1arg2(0)uminusc(1)*b(0)(2)uminusc(3)*b(2)(4)+(1)(3)(5)assigna(4),三地址语句,xi:=y op arg1 arg2(0)=x i(1)assign(0)yx:=yiop arg1 arg2(0)=y i(1)assign x(0),三地址语句,间接三元式 为了便于优化,用 三元式表+间接码表 表示中间代码间接码表:一张指示器表,按运算的先后次序列出有关三元式在三元式表中的位置。优点:方便优化,节省空间,例如,语句X:=(A+B)*C;Y:=D(A+B)的间接三元式表示如下表所示。,7.2 声 明 语 句,声明的语法制导定义,7.2 声 明 语 句,D id L addtype(id.entry,L.type)L,id L1 L.type:=L1.Type;addtype(id.entry,L1.type)L:T L.type:=T.typeT integer T.type:=integerT real T.type:=real以上没有继承属性的翻译方案,7.2 声 明 语 句,为局部名字建立符号表条目为它分配存储单元符号表中包含名字的类型和分配给它的存储单元的相对地址等信息,7.2 声 明 语 句,过程中的声明,P D SD D;D D id:TT integer T realT array num of T1T T1,7.2 声 明 语 句,计算被声明名字的类型和相对地址P offset:=0D SD D;D D id:Tenter(id.name,T.type,offset);offset:=offset+T.width T integer T.type:=integer;T.width:=4 T real T.type:=real;T.width:=8 T array num of T1T.type:=array(num.val,T1.type);T.width:=num.val T1.widthT T1 T.type:=pointer(T1.type);T.width:=4 offset:用于跟踪可用的相对地址的位置。enter(name,type,offset):用于填充符号表。,7.2 声 明 语 句,7.2.2 作用域信息的保存所讨论语言的文法P D SD D;D|id:T|proc id;D;S 语义动作用到的函数mktable(previous)enter(table,name,type,offset)addwidth(table,width)enterproc(table,name,newtable),7.2 声 明 语 句,处理嵌套过程中的说明语句P M D S addwidth(top(tblptr),top(offset);pop(tblptr);pop(offset)M t:=mktable(nil);push(t,tblprt);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.width N t:=mktable(top(tblptr);push(t,tblptr);push(0,offset)tblptr与offset是两个栈名,tblptr为主过程的符号表头,offset为存放各嵌套过程的当前相对地址。,7.2 声 明 语 句,7.3 赋值语句的翻译,7.3.1 简单算术表达式及赋值语句,为赋值语句生成三地址代码的S-属性文法定义,产生式语义规则Sid:=ES.code:=E.code|gen(id.place:=E.place)EE1+E2E.place:=newtemp;E.code:=E1.code|E2.code|gen(E.place:=E1.place+E2.place)EE1*E2E.place:=newtemp;E.code:=E1.code|E2.code|gen(E.place:=E1.place*E2.place)E-E1E.place:=newtemp;E.code:=E1.code|gen(E.place:=uminus E1.place)E(E1)E.place:=E1.place;E.code:=E1.codeEid E.place:=id.place;E.code=,产生赋值语句三地址代码的翻译模式,Sid:=E p:=lookup(id.name);if pnil thenemit(p:=E.place)else error EE1+E2 E.place:=newtemp;emit(E.place:=E1.place+E2.place)EE1*E2 E.place:=newtemp;emit(E.place:=E 1.place*E 2.place),产生赋值语句三地址代码的翻译模式,E-E1 E.place:=newtemp;emit(E.place:=uminusE 1.place)E(E1)E.place:=E1.placeEid p:=lookup(id.name);if pnil then E.place:=p else error,7.3.2 数组元素的引用,数组元素地址的计算:,设A为n维数组,每个元素宽度为w,lowi 为第i维 的下界,ni 是为第i维 可取值的个数,base为A的第一个元素相对地址 元素Ai1,i2,ik相对地址公式(i1 n2+i2)n3+i3)nk+ik)w+base-(low1 n2+low2)n3+low3)nk+lowk)w C=base-(low1 n2+low2)n3+low3)nk+lowk)w,id出现的地方也允许下面产生式中的L出现 L id Elist|idElistElist,E|E 为了便于处理,文法改写为 LElist|id ElistElist,E|id E,引入下列语义变量或语义过程:Elist.ndim:下标个数计数器Elist.place:表示临时变量,用来临时存放已形成的Elist中的下标表达式计算出来的值 Elist.array:记录指向符号表中相应树组名字表项的指针limit(array,j):函数过程,它给出数组array的第j维的长度,每个代表变量的非终结符L有两项语义值L.place:若L为简单变量i,指变量i的符号表入口 若L为下标变量,指存放CONSPART的临时变量的整数码 L.offset:若L为简单变量,null,若L为下标变量,指存放VARPART的临时变量的整数码,(1)SL:=E(2)EE+E(3)E(E)(4)EL(5)LElist(6)Lid(7)Elist Elist,E(8)Elistid E,(1)SL:=E if L.offset=null then/*L是简单变量*/emit(L.place:=E.place)else emit(L.place L.offset:=E.place)(2)EE1+E2 E.place:=newtemp;emit(E.place:=E 1.place+E 2.place),(3)E(E1)E.place:=E1.place(4)EL if L.offset=null then E.place:=L.place else begin E.place:=newtemp;emit(E.place:=L.place L.offset)end,Ai1,i2,ik(i1 n2+i2)n3+i3)nk+ik)w+base-(low1 n2+low2)n3+low3)nk+lowk)w,(8)Elistid E Elist.place:=E.place;Elist.ndim:=1;Elist.array:=id.place,Ai1,i2,ik(i1 n2+i2)n3+i3)nk+ik)w+base-(low1 n2+low2)n3+low3)nk+lowk)w,(7)Elist Elist1,E t:=newtemp;m:=Elist1.ndim+1;emit(t:=Elist1.place*limit(Elist1.array,m);emit(t:=t+E.place);Elist.array:=Elist1.array;Elist.place:=t;Elist.ndim:=m,Ai1,i2,ik(i1 n2+i2)n3+i3)nk+ik)w+base-(low1 n2+low2)n3+low3)nk+lowk)w,(5)LElist L.place:=newtemp;emit(L.place:=Elist.array C);L.offset:=newtemp;emit(L.offset:=w*Elist.place)(6)Lid L.place:=id.place;L.offset:=null,例:赋值语句:x:=Ay,z,T1:=y*20T1:=T1+zT2:=A-84T3:=4*T1T4:=T2T3x:=T4,类型转换,用E.type表示非终结符E的类型属性 对应产生式EE1 op E2的语义动作中关于E.type的语义规则可定义为:if E1.type=integer a E2.type=integer E.type:=integer else E.type:=real 算符区分为整型算符int op和实型算符real op,,x:=yi*j 其中x、y为实型;i、j为整型。这个赋值句产生的三地址代码为:T1:=i int*j T3:=inttoreal T1 T2:=y real+T3 x:=T2,关于产生式EE1 E2 的语义动作,E.place:=newtemp;if E1.type=integer and E2.type=integer then begin emit(E.place:=E 1.place int+E 2.place);E.type:=integer end else if E1.type=real and E2.type=real then begin emit(E.place:=E 1.place real+E 2.place);E.type:=real end,else if E1.type=integer and E2.type=real then beginu:=newtemp;emit(u:=inttoreal E 1.place);emit(E.place:=u real+E 2.palce);E.type:=realendelse if E1.type=real and E1.type=integer then beginu:=newtemp;emit(u:=inttoreal E 2.place);emit(E.place:=E 1.place real+u);E.type:=realend else E.type:=type_error,7.3.3 记录中域的引用,符号表表项之中保存记录中的域的类型和相对地址信息,7.4 布尔表达式的翻译,布尔表达式的两个基本作用:用于逻辑演算,计算逻辑值;用于控制语句的条件式.产生布尔表达式的文法:EE or E|E and E|E|(E)|i rop i|i,计算布尔表达式通常采用两种方法:1.如同计算算术表达式一样,一步步算 1 or(not 0 and 0)or 0=1 or(1 and 0)or 0=1 or 0 or 0=1 or 0=12.采用某种优化措施 把A or B解释成 if A then true else B 把A and B解释成 if A then B else false 把 A解释成 if A then false else true,两种不同的翻译方法:第一种翻译法:A or B and C=D翻译成(1)(=,C,D,T1)(2)(and,B,T1,T2)(3)(or,A,T2,T3)第二种翻译法适合于作为条件表达式的布尔表达式使用.,7.4.1 数值表示法,a or b and not c 翻译成T1:=not cT2:=b and T1T3:=a or T1ab的关系表达式可等价地写成if ab then 1 else 0,翻译成 100:if ab goto 103101:T:=0102:goto 104103:T:=1104:,关于布尔表达式的数值表示法的翻译模式,过程emit将三地址代码送到输出文件中nextstat给出输出序列中下一条三地址语句的地址索引每产生一条三地址语句后,过程emit便把nextstat加1,关于布尔表达式的数值表示法的翻译模式,EE1 or E2 E.place:=newtemp;emit(E.place:=E 1.place or E2.place)EE1 and E2 E.place:=newtemp;emit(E.place:=E 1.place and E2.place)Enot E1 E.place:=newtemp;emit(E.place:=not E 1.place)E(E1)E.place:=E1.place,Eid1 relop id2 E.place:=newtemp;emit(if id1.place relop.op id2.place goto nextstat+3);emit(E.place:=0);emit(goto nextstat+2);emit(E.place:=1)Eid E.place:=id.place,关于布尔表达式的数值表示法的翻译模式,布尔表达式ab or cd and ef翻译成如下的一串三地址代码,布尔表达式ab or cd and ef翻译成如下的一串三地址代码,100:if ab goto 103101:T1:=0102:goto 104103:T1:=1104:if cd goto 107105:T2:=0106:goto 108,107:T2:=1108:if ef goto 111109:T3:=0110:goto 112111:T3:=1112:T4:=T2 and T3113:T5:=T1 or T4,7.4.2 作为条件控制的布尔式翻译,条件语句 if E then S1 else S2 赋予 E 两种出口:一真一假,E.code,S1.code,S2.code,To E.true,To E.false,goto S.next,S.next,E.true:,E.false:,例:把语句:if ac or b c goto L2“真”出口 goto L1L1:if bd goto L2“真”出口 goto L3“假”出口 L2:(关于S1的三地址代码序列)goto LnextL3:(关于S2的三地址代码序列)Lnext:考虑and 的语义跟 or 的语义的不同,每次调用函数newlabel后都返回一个新的符号标号,用于标识一条三地址语句.对于一个布尔表达式E,引用两个标号E.true是E为真时控制流转向的标号E.false是E为假时控制流转向的标号,产生布尔表达式三地址代码的语义规则,产生式语义规则 EE1 or E2E1.true:=E.true;E1.false:=newlabel;E2.true:=E.true;E2.false:=E.false;E.code:=E1.code|gen(E1.false:)|E2.code,表达式中执行goto哪里去了呢?,产生布尔表达式三地址代码的语义规则,产生式语义规则EE1 and E2E1.true:=newlabel;E1.false:=E.false;E2.true:=E.true;E2.false:=E.fasle;E.code:=E1.code|gen(E1.true:)|E2.codeEnot E1 E1.true:=E.false;E1.false:=E.true;E.code:=E1.code,表达式中执行goto哪里去了呢?,产生布尔表达式三地址代码的语义规则,产生式语义规则 E(E1)E1.true:=E.true;E1.false:=E.false;E.code:=E1.code Eid1 relop id2E.code:=gen(if id1.place relop.op id2.place goto E.true)|gen(goto E.false)Etrue E.code:=gen(goto E.true)Efalse E.code:=gen(goto E.false),考虑如下表达式:ab or cd and ef假定整个表达式的真假出口已分别置为Ltrue和Lfalse,则按定义将生成如下的代码:,if ab goto Ltruegoto L1L1:if cd goto L2goto LfalseL2:if ef goto Ltruegoto Lfalse只有整个表达式的真假出口不确定,而子表达式中的内部跳转地址都是确定的,布尔表达式的翻译,两遍扫描为给定的输入串构造一棵语法树;对语法树进行深度优先遍历,进行语义规则中规定的翻译。一遍扫描在很多情况下,不确定将要转移到的标号是多少。,一遍扫描实现布尔表达式的翻译,采用四元式形式把四元式存入一个数组中,数组下标就代表四元式的标号约定 四元式(jnz,a,-,p)表示 if a goto p 四元式(jrop,x,y,p)表示 if x rop y goto p四元式(j,-,-,p)表示 goto p,有时,四元式转移地址无法立即知道,我们只好把这个未完成的四元式地址作为E的语义值保存,待机回填。为非终结符E赋予两个综合属性E.truelist和E.falselist。它们分别记录布尔表达式E所对应的四元式中需回填“真”、“假”出口的四元式的标号所构成的链表,例如:假定E的四元式中需要回填真出口的p,q,r三个四元式,则E.truelist为下列链:(p)(x,x,x,0)(q)(x,x,x,p)(r)(x,x,x,q),链尾,E.truelist=r,为了处理E.truelist和E.falselist,引入下列语义变量和过程:变量nextquad,它指向下一条将要产生但尚未形成的四元式的地址(标号)。nextquad的初值为1,每当执行一次emit之后,nextquad将自动增1。函数makelist(i),它将创建一个仅含i的新链表,其中i是四元式数组的一个下标(标号);函数返回指向这个链的指针。函数merge(p1,p2),把以p1和p2为链首的两条链合并为一,作为函数值,回送合并后的链首。过程backpatch(p,t),其功能是完成“回填”,把p所链接的每个四元式的第四区段都填为t。,布尔表达式的文法,(1)EE1 or M E2(2)|E1 and M E2(3)|not E1(4)|(E1)(5)|id1 relop id2(6)|id(7)M,布尔表达式的翻译模式,(1)EE1 or M E2 backpatch(E1.falselist,M.quad);E.truelist:=merge(E1.truelist,E2.truelist);E.falselist:=E2.falselist(2)EE1 and M E2 backpatch(E1.truelist,M.quad);E.truelist:=E2.truelist;E.falselist:=merge(E1.falselist,E2.falselist),布尔表达式的翻译模式,(3)Enot E1 E.truelist:=E1.falselist;E.falselist:=E1.truelist(4)E(E1)E.truelist:=E1.truelist;E.falselist:=E1.falselist,布尔表达式的翻译模式,(5)Eid1 relop id2 E.truelist:=makelist(nextquad);E.falselist:=makelist(nextquad+1);emit(j relop.op,id 1.place,id 2.place,0);emit(j,0)(6)Eid E.truelist:=makelist(nextquad);E.falselist:=makelist(nextquad+1);emit(jnz,id.place,0);emit(j,-,-,0),布尔表达式的翻译模式,(7)M M.quad:=nextquad 作为整个布尔表达式的真假出口(转移目标)仍待回填.,ab or cd and ef,100(j,a,b,0)101(j,-,-,102)102(j,c,d,104)103(j,-,-,0)104(j,e,f,100)truelist105(j,-,-,103)falselist,7.5 控制语句的翻译,考虑下列产生式所定义的语句 S if E then S1|if E then S1 else S2|while E do S1其中E为布尔表达式。,if-then语句S if E then S1,E.code,S1.code,To E.true,To E.false,E.true:,E.false:,if-then语句的属性文法,产生式语义规则 Sif E then S1E.true:=newlabel;E.flase:=S.next;S1.next:=S.next S.code:=E.code|gen(E.true:)|S1.code,if-then-else语句S if E then S1 else S2,E.code,S1.code,S2.code,To E.true,To E.false,goto S.next,S.next,E.true:,E.false:,if-then-else语句的属性文法,产生式 语义规则Sif E then S1 else S2 E.true:=newlabel;E.false:=newlabel;S1.next:=S.next S2.next:=S.next;S.code:=E.code|gen(E.true:)|S1.code|gen(goto S.next)|gen(E.false:)|S2.code,while-do语句S while E do S1,E.code,S1.code,To E.true,To E.false,goto S.begin,S.begin:,E.true:,E.false:,while-do语句的属性文法,产生式语义规则Swhile E do S1S.begin:=newlabel;E.true:=newlabel;E.false:=S.next;S1.next:=S.begin;S.code:=gen(S.begin:)|E.code|gen(E.true:)|S1.code|gen(goto S.begin),考虑如下语句:while ab doif cd thenx:=y+z else x:=y-z,考虑如下语句:while ab doif cd thenx:=y+z else x:=y-z,生成下列代码:L1:if ab goto L2goto LnextL2:if cd goto L3goto L4L3:T1:=y+zx:=T1goto L1L4:T2:=y-zx:=T2goto L1Lnext:,一遍扫描翻译控制流语句,考虑下列产生式所定义的语句:(1)Sif E then S(2)|if E then S else S(3)|while E do S(4)|begin L end(5)|A(6)LL;S(7)|SS表示语句,L表示语句表,A为赋值语句,E为一个布尔表达式,if 语句的翻译相关产生式S if E then S(1)|if E then S(1)else S(2)改写后产生式 S if E then M S1 S if E then M1 S1 N else M2 S2 M N,翻译模式:1.Sif E then M S1 backpatch(E.truelist,M.quad);S.nextlist:=merge(E.falselist,S1.nextlist)2.Sif E then M1 S1 N else M2 S2 backpatch(E.truelist,M1.quad);backpatch(E.falselist,M2.quad);S.nextlist:=merge(S1.nextlist,N.nextlist,S2.nextlist)3.M M.quad:=nextquad 4.N N.nextlist:=makelist(nextquad);emit(j,),while 语句的翻译相关产生式S while E do S(1)翻译为:,E的代码,S(1)的代码,“真”出口,“假”出口,为了便于回填,改写产生式为:Swhile M1 E do M2 S1 M,翻译模式:1.Swhile M1 E do M2 S1 backpatch(S1.nextlist,M1.quad);backpatch(E.truelist,M2.quad);S.nextlist:=E.falselistemit(j,M1.quad)2.M M.quad:=nextquad,产生式 LL;S改写为:LL1;M SM,翻译模式:1.LL1;M S backpatch(L1.nextlist,M.quad);L.nextlist:=S.nextlist 2.M M.quad:=nextquad,其它几个语句的翻译1.Sbegin L end S.nextlist:=L.nextlist 2.SA S.nextlist:=makelist()3.LS L.nextlist:=S.nextlist,翻译语句while(ab)doif(cd)then x:=y+z;,100(j,a,b,102)101(j,-,-,107)102(j,c,d,104)103(j,-,-,100)104(+,y,z,T)105(:=,T,-,x)106(j,-,-,100)107,7.5.2 标号与goto语句,标号定义形式L:S;标号引用goto L;示例:,向后转移:L1:goto L1;,向前转移:goto L1;L1:,产生式Sgoto L的语义动作:查找符号表;IF L在符号表中且定义否栏为已 THEN GEN(J,-,-,P)ELSE IF L不在符号表中 THEN BEGIN把L填入表中;置定义否为未,地址栏为NXQ;GEN(J,-,-,0)END ELSE BEGIN Q:=L的地址栏中的编号;置地址栏编号为NXQ;GEN(J,-,-,Q)END,带标号语句的产生式:Slabel S label i:label i:对应的语义动作:1.若i所指的标识符(假定为L)不在符号表中,则把它填入,置类型为标号,定义否为已,地址为nextquad;2.若L已在符号表中但类型不为标号或定义否为已,则报告出错;3.若L已在符号表中,则把标号未改为已,然后,把地址栏中的链头(记为q)取出,同时把nextquad填在其中,最后,执行BACKPATCH(q,nextquad)。,7.5.3 CASE语句的翻译,语句结构case E ofC1:S1;C2:S2;Cn-1:Sn-1;otherwise:Snend,翻译法(一):T:=EL1:if TC1 goto L2 S1的代码 goto nextL2:if TC2 goto L3 S2的代码 goto nextL3:Ln-1:if TCn-1 goto Ln Sn-1的代码 goto nextLn:Sn的代码next:,改进:,翻译法(二):计算E并放入T中goto testL1:关于S1的中间码goto nextLn-1:关于Sn-1的中间码goto nextLn:关于Sn的中间码goto nexttest:if T=C1 goto L1if T=C2 goto L2if T=Cn-1 goto Ln-1goto Lnnext:,(case,C1,P1)(case,C2,P2)(case,Cn-1,Pn-1)(case,T,Pn)(label,NEXT,-,-),Pi是LI在符号表中的位置,7.6 过程调用的处理,过程调用主要对应两种事:传递参数转子程序,传地址:把实在参数的地址传递给相应的形式参数调用段预先把实在参数的地址传递到被调用段可以拿到的地方;程序控制转入被调用段之后,被调用段首先把实在参数的地址抄进自己相应的形式单元中;过程体对形式参数的引用域赋值被处理成对形式单元的间接访问。,翻译方法:把实参的地址逐一放在转子指令的前面.例如,CALL S(A,X+Y)翻译为:计算X+Y置于T中的代码 par A/*第一个参数的地址*/par T/*第二个参数的地址*/call S/*转子*/,过程调用的翻译,过程调用文法:(1)S call id(Elist)(2)Elist Elist,E(3)Elist E,翻译模式 1.Scall id(Elist)for 队列queue中的每一项p do emit(param p);emit(call id.place)2.ElistElist,E 将E.place加入到queue的队尾 3.ElistE 初始化queue仅包含E.place,作业,P1333,4,6,7,

    注意事项

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

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




    备案号:宁ICP备20000045号-2

    经营许可证:宁B2-20210002

    宁公网安备 64010402000987号

    三一办公
    收起
    展开