第七章语义分析和中间代码生成

上传人:re****.1 文档编号:568293991 上传时间:2024-07-24 格式:PPT 页数:157 大小:779.50KB
返回 下载 相关 举报
第七章语义分析和中间代码生成_第1页
第1页 / 共157页
第七章语义分析和中间代码生成_第2页
第2页 / 共157页
第七章语义分析和中间代码生成_第3页
第3页 / 共157页
第七章语义分析和中间代码生成_第4页
第4页 / 共157页
第七章语义分析和中间代码生成_第5页
第5页 / 共157页
点击查看更多>>
资源描述

《第七章语义分析和中间代码生成》由会员分享,可在线阅读,更多相关《第七章语义分析和中间代码生成(157页珍藏版)》请在金锄头文库上搜索。

1、第七章第七章 语义分析和中间代码生成语义分析和中间代码生成本章内容本章内容介绍几种常用的中间表示介绍几种常用的中间表示:后缀表示、图形后缀表示、图形表示和三地址代码表示和三地址代码用语法制导定义和翻译方案的方法来说明程用语法制导定义和翻译方案的方法来说明程序设计语言的结构怎样被翻译成中间形式序设计语言的结构怎样被翻译成中间形式 分析分析器器静态静态检查检查器器中间中间代码代码生成生成器器中间中间代码代码记记号号流流代码代码生成生成器器详瓶秦弥裁楚赁赢咙恭征视仑隘埠俏狞蓖窄灵纤箕橇通征列剑润怠隐瓶撵第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.1 中中 间间 语语 言言7.1.1后

2、缀式后缀式表达式表达式E的的后缀式后缀式可以如下递归定义可以如下递归定义如果如果E E是变量或常数,那么是变量或常数,那么E的后缀的后缀式式就是就是E本本身。身。荡走翁溉抹翔盗就说怜躯卯甚棕近虎疙舞赚掸藏念合垄竞懊具奖惋搀秘吃第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.1 中中 间间 语语 言言7.1.1后缀表示后缀表示表达式表达式E的的后缀表示后缀表示可以如下递归定义可以如下递归定义如果如果E E是变量或常数,那么是变量或常数,那么E的后缀表示就是的后缀表示就是E本身。本身。如果如果E是形式为是形式为E1opE2的表达式,那么的表达式,那么E的后的后缀式是缀式是E1 E2 o

3、p,其中,其中E1 和和E2 分别是分别是E1和和E2的后缀式。的后缀式。钨猛热附磐幌冗脂淫腑雪滴警进皇柑障更夜乱汰烛酮禾卞弟磁轴垄刺埠暴第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.1 中中 间间 语语 言言7.1.1后缀式后缀式表达式表达式E的的后缀式后缀式可以如下递归定义可以如下递归定义如果如果E E是变量或常数,那么是变量或常数,那么E的后缀的后缀式式就是就是E本本身。身。如果如果E是形式为是形式为E1opE2的表达式,那么的表达式,那么E的后的后缀式是缀式是E1 E2 op,其中,其中E1 和和E2 分别是分别是E1和和E2的后缀式。的后缀式。如果如果E是形式为是形式为

4、(E1)的表达式,那么的表达式,那么E1的后缀的后缀表示也是表示也是E的后缀的后缀式。式。 喉片笼嘿免冷垂凸泽釉甲驹庞娘二滤大萨努抱乱肚锥拼猴撇客厢立酋律峦第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.1 中中 间间 语语 言言后缀式表示法是波兰逻辑学家卢卡西维奇后缀式表示法是波兰逻辑学家卢卡西维奇(LukasiewiczLukasiewicz)发明的一种表示表达式的方)发明的一种表示表达式的方法因此又称逆波兰表示法。这种表示法是把法因此又称逆波兰表示法。这种表示法是把运算量(操作数)写在前面把算符写在后面运算量(操作数)写在前面把算符写在后面(后缀)。(后缀)。 果确薯剃翼畴历

5、萍纸凭凉槽戴糜努牵侧叮煽盘搓阶魁合良瞻噎秉育电讲瑰第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.1 中中 间间 语语 言言把表达式翻译为后缀式的语义规则描述把表达式翻译为后缀式的语义规则描述产产生生式式语语义义规规则则EE1opE2E.code:E1.code|E2.code|opE(E1)Ecode:=E1.codeEidEcode:id抚嚏嫌瘦为皋瘴宫升掣飞儿刹递冯跌炮揪阂迢然块漳鼻廷沉待抨躁促溃曼第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.1 中中 间间 语语 言言后缀后缀式式不需要括号不需要括号(8 4)+2的后缀表示是的后缀表示是84 2+ 后缀后缀式式

6、的最大优点是便于计算机处理表达式的最大优点是便于计算机处理表达式后缀后缀式式很容易拓广到含一元算符的表达式很容易拓广到含一元算符的表达式 后缀后缀式式也可以拓广到表示赋值语句和控制语也可以拓广到表示赋值语句和控制语句,但很难用栈来描述它的计算句,但很难用栈来描述它的计算趾纯跌椰徊肾迸肮典硬穗姓沧课阔觅焉羞哄豁饵谗聚鸵勿骡春罕琳乖琶瘫第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.1 中中 间间 语语 言言7.1.2 图形表示图形表示图表示法包括图表示法包括DAG与抽象语法树与抽象语法树语法树是一种图形化的中间表示语法树是一种图形化的中间表示assigna+ bcdcduminus(

7、a)语法树语法树a:=( b+c d)+c d的图形的图形表示表示耍迟橇灼哩卞条杆羊讨孰弥钝搞缅浑呼箍女杖窑氦乖略倦瓦僧孽蒲聋祷浙第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.1 中中 间间 语语 言言7.1.2 图形表示图形表示语法树是一种图形化的中间表示语法树是一种图形化的中间表示有向无环图有向无环图也是一种中间表示也是一种中间表示 assigna+ bcdcduminusassigna+ bcduminus(a)语法树语法树(b)DAGa:=( b+c d)+c d的图形的图形表示表示戏嘛鼠脏约腾派节哆踞佰惮究危听恢痴埂驰彝谣吐瘤粳凤贤崭税沉铝歹佐第七章语义分析和中间代码生

8、成第七章语义分析和中间代码生成7.1 中中 间间 语语 言言构造赋值语句语法树的语法制导定义构造赋值语句语法树的语法制导定义产产生生式式语语义义规规则则S id:=E S.nptr:=mknode(assign,mkleaf (id,id.entry), E.nptr)E E1+E2 E.nptr:=mknode(+,E1.nptr, E2.nptr)E E1 E2E.nptr:=mknode( ,E1.nptr, E2.nptr)E E1E.nptr:=mkunode(uminus,E1.nptr)E (E1)E.nptr:=E1.nptrF idE.nptr:=mkleaf (id,id.

9、entry)爱柠房旁象宣与颂洲羊讽绅舀枣兑军察净壳镇挤甩伶唤绳刻勃筒泥传离抗第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.1 中中 间间 语语 言言7.1.3三地址代码三地址代码一般形式:一般形式:x:=y op z表达式表达式x +y z翻译成的三地址语句序列是翻译成的三地址语句序列是t1:=y zt2:=x +t1摩村彪悔婉夯额梁搭量倪熊基索顿窃蕊峭丝酝题诧逐俩描额增筐固俩绰庐第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.1 中中 间间 语语 言言三地址代码是语法树或三地址代码是语法树或DAG的一种线性表示的一种线性表示a:=( b+c d)+c d语法树的代码

10、语法树的代码DAG的代码的代码t1:= bt1:= bt2:=c dt2:=c dt3:=t1+t2t3:=t1+t2t4:=c dt4:=t3+ t2t5:=t3+ t4 a:=t4a:=t5娘萤寥吃帖弃底垃汹嘲钓喳舶武碱卵仪刨巡叶责桐烹冰糊检说蒂曾焙拭辊第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.1 中中 间间 语语 言言本书常用的三地址语句本书常用的三地址语句赋值语句赋值语句x:=y op z,x:=op y, x:=y无条件转移无条件转移gotoL条件转移条件转移ifx relopygotoL过程调用过程调用paramx和和callp,n过程返回过程返回return y

11、索引赋值索引赋值x:=yi和和xi:=y地址和指针赋值地址和指针赋值x:=&y,x:= y和和 x:=y汇世国请喳软赛噬馁榔羚赦伶沟宇玖滚乒丢以访扎蛔购稀切榨桃滁有搪冤第七章语义分析和中间代码生成第七章语义分析和中间代码生成T1:y*zT2:xT1T1:=cT1:=cT2:=b*T1T2:=b*T1T3:=cT5:=T2+T4T4:=b*T3a:=T5T5:=T2+T4a:=T5图7.5相应于图7.3的树和DAG的三地址代码(a)对于抽象语法树的代码;(b)对于DAG的代码诞七号擎竟尺谭翌肪滤简首翘贪近绊督僳戮沏厘尧竖昂彦嘿涂坪谬畴巳颗第七章语义分析和中间代码生成第七章语义分析和中间代码生成四

12、元式、三元式、间接三元式三地址语句可看成中间代码的一种抽象形式。编译程序中,三地址代码语句的具体实现可以用记录表示,记录中包含表示运算符和操作数的域。通常有三种表示方法:四元式、三元式、间接三元式。捌迷沾异使低卯晚涎巩靡衣坞避捞骋仔洲悔竖骂藻掠钩食肩莹耐努袭抖砍第七章语义分析和中间代码生成第七章语义分析和中间代码生成a:b*cb*c四元式三元式oparg1arg2resultoparg1arg2(0)uminuscT1(0)uminusc(1)*bT1T2(1)*b(0)(2)uminuscT3(2)uminusc(3)*bT3T4(3)*b(2)(4)+T2T4T5(4)+(1)(3)(5)

13、:=T5a(5)assigna(4)汉那欧倔舞辟败攒潦价似差蜕次归褒教文临藤酒引畸候菜礁酬笋羔诗打升第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.2 说说 明明 语语 句句为局部名字建立符号表条目为局部名字建立符号表条目为它分配存储单元为它分配存储单元符号表中包含名字的类型和分配给它的存储符号表中包含名字的类型和分配给它的存储单元的相对地址等信息单元的相对地址等信息腔柒狼呵腕辅堰莉名馏柜莱袱烦噶蓄骂尽霸遗伟桅眼饲疲拌栅焰颐妹甫钙第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.2 说说 明明 语语 句句7.2.1 过程中的声明过程中的声明财娶计寅偿穿戳咀娟刹溅尤棕递蚕夺

14、致笆斑朝鼎属澡梢磅笆愧猖拇贬旱淤第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.2 说说 明明 语语 句句计算被声明名字的类型和相对地址计算被声明名字的类型和相对地址P D offset:=0D D ;DD id:T enter(id.name,T.type,offset); offset :=offset +T.widthT integerT.type := integer;T.width:=4TrealT.type :=real;T.width:=8TarraynumofT1T.type:=array(num.val, T1.type);T.width:=num.val T1.

15、widthT T1T.type :=pointer (T1.type);T.width:=4由垫谨氢送盎傀牡字莎娩葫肌侦惹愈锭拔甚珐季矽族妊隧踢清疮恫量祖郴第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.2 说说 明明 语语 句句7.2.2作用域信息的保存作用域信息的保存所讨论语言的文法所讨论语言的文法P D SD D ; D | id: T | procid; D; S 语义动作用到的函数语义动作用到的函数mktable(previous)enter(table, name, type, offset) addwidth(table,width)enterproc(table,n

16、ame,newtable)千纯祝签烙驯挚找咳挫痰臼振际买秤雇绝始倪岗害愈佛滚兆嘶敲锑凯摊稍第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.2 说说 明明 语语 句句处理嵌套过程中的说明语句处理嵌套过程中的说明语句P M D addwidth(top(tblptr),top(offset);pop(tblptr);pop(offset)M t:=mktable(nil);push(t,tblprt);push(0,offset)D D1;D2D procid;N D1;St:=top(tblptr); addwidth(t,top(offset);pop(tblptr);pop(of

17、fset); 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)良障症要邮签纸毗释吩招寅札庚耘支走荣扳佣憋朔涛廊的路吱萨窿屈畜沸第七章语义分析和中间代码生成第七章语义分析和中间代码生成(1)programsort(input,output)(2)vara:array0.10ofinteger;(3)x:

18、integer;(4)procedurereadarray(5)vari:integer;(6)beginaendreadarray(7)procedureexchange(i,j:integer);(8)begin(9)x:=ai;ai:=aj;aj:=x(10)endexchange;(11)procedurequicksort(m,n;integer);(12)vark,v:integer;(13)functionpartition(y,z:integer):integer;(14)vari,j:integer;(15)begina(16)v(17)exchange(i,j);(18)e

19、ndpartition;(19)beginendquicksort;(20)beginendsort.蓉记圈系蚀瞅咽仁申帆囚驰爷嫡岭缠疾返阴柳兵凤危诸除麓诲蠕拟铺缘象第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.2 说说 明明 语语 句句exchangereadarrayxa表表头头空空sortquicksort指向指向readarraypartitionvk表表头头quicksortreadarraryi表表头头exchange表表头头指向指向exchangepartition眯垂所作躯莫汹骨请矣凿歹赤盯歹涟刹纬慨筒肯绳且搭捅竣稗情看盯宵意第七章语义分析和中间代码生成第七章语义

20、分析和中间代码生成7.2 说说 明明 语语 句句7.2.3 记录的域名记录的域名T recordD endT recordLD endT.type :=record(top(tblptr);T.width:=top(offset);pop(tblptr);pop(offset)L t:=mktable(nil);push(t,tblprt);push(0,offset)帕螺谣笔策等铂颊评壶那谍渠胁咒廊生路餐肘耳致陌毯于率跳番柑彬桂吕第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.3 赋赋 值值 语语 句句7.3.1简单算术表达式及赋值语句简单算术表达式及赋值语句S id:=E p:

21、=lookup(id.name);ifp nilthenemit(p,:=,E.place)elseerrorE E1+E2E.place:=newtemp;emit(E.place,:=,E1.place,+,E2.place)轰犀施猫咀现玛氯挥悸蝴蹄瘟辟联陆论畴孔入疵铂钝嗜棕沏努布拽揪掺使第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.3 赋赋 值值 语语 句句7.3.1简单算术表达式及赋值语句简单算术表达式及赋值语句E E1E.place:=newtemp; emit(E.place,:=,uminus,E1.place)E (E1)E.place:=E1.placeE id

22、p:=lookup(id.name);ifp nilthenE.place:=p elseerror 赐愁肃便孕辊迂女售软沛温齐暇菇投天搬硼叹球悉影狼糯缮火湍替乎渝泌第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.3 赋赋 值值 语语 句句7.3.2数组元素的地址计算数组元素的地址计算一维数组一维数组A的第的第i个元素的地址计算个元素的地址计算base+(i low ) w牺珐球蕊蛹高斟屡颗希式煮槽蛛祈硫勘呼准羞琼毗颧笼霍南账仗本胞宇憨第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.3 赋赋 值值 语语 句句7.3.3数组元素的地址计算数组元素的地址计算一维数组一维数组

23、A的第的第i个元素的地址计算个元素的地址计算base+(i low ) w重写成重写成i w +(base low w)颐洪伦卡偏榴嘻湖服泥践赠闺燕火舞潘倒羞拟蒙燥蔼拴玻熙钾霄晾培湾箱第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.3 赋赋 值值 语语 句句二维数组二维数组列为主列为主A1,1,A2,1,A1,2,A2,2,A1,3,A2,3洁伎小酚庙夫暴原寸群瞅聋识型答骤沙昧夏害逊列亏勇榔泣囱赏孤守峰儡第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.3 赋赋 值值 语语 句句二维数组二维数组列为主列为主A1,1,A2,1,A1,2,A2,2,A1,3,A2,3行为主行

24、为主A1,1,A1,2,A1,3,A2,1,A2,2,A2,3焉割戎藉弥溜六歧剿蹭湖虱啤瓷锑要央墅苔勿拆糜察被霄规梳抉惟贺瘤办第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.3 赋赋 值值 语语 句句二维数组二维数组列为主列为主A1,1,A2,1,A1,2,A2,2,A1,3,A2,3行为主行为主A1,1,A1,2,A1,3,A2,1,A2,2,A2,3base+(i1 low1) n2+(i2 low2) w(其中(其中n2=high2 low2+1)塘稗毁奔檀噬矛茬诛身镰镰领汾习喇厌彦吓安寅碧冰据币荣撼咀则竿可挠第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.3 赋

25、赋 值值 语语 句句二维数组二维数组列为主列为主A1,1,A2,1,A1,2,A2,2,A1,3,A2,3行为主行为主A1,1,A1,2,A1,3,A2,1,A2,2,A2,3base+(i1 low1) n2+(i2 low2) w(其中(其中n2=high2 low2+1)(i1 n2)+i2) w +(base (low1 n2)+low2) w)幸琼豢肿烟治雏次抡枪烹逸脊绪兑仙料市接俱皮戊刽铭五梆夜住声膜膜谰第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.3 赋赋 值值 语语 句句多维数组多维数组Ai1,i2,.,ik 的地址表达式的地址表达式(i1 n2+i2 ) n3

26、+ i3) nk + ik) w+base (low1 n2+low2) n3 + low3) nk + lowk) w室操稼调阁诵抱廊向渡涅潜幂仪笨赣人典洋莎仟牲葡自浓很引绣镇催捂芋第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.3 赋赋 值值 语语 句句7.3.4数组元素地址计算的翻译方案数组元素地址计算的翻译方案下标变量访问的产生式下标变量访问的产生式L idElist|idElist Elist,E |E改成改成L Elist|idElist Elist,E |idE石幼蔗酋埂哑毁叁屎寅仓受扇消宵狂歌既绕署寐莉等晾邯滋银歇酶昭咱垂第七章语义分析和中间代码生成第七章语义分析和

27、中间代码生成7.3 赋赋 值值 语语 句句所有产生式所有产生式S L :=EE E+EE (E)E LL Elist L idElistElist,EElistidE三酚徊亢娶裸峨玫浊肃遵缀殖阅庐镇巩拱刽抱湾羽芦这五耐帐恒尊仟骸刑第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.3 赋赋 值值 语语 句句L idL.place:=id.place;L.offset:=null迟拢趴砖扣展碑叙旱儒商侦矣仿践袖郧悟肾妒紊辰芒损叉靴咯掩蔬丁帝纤第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.3 赋赋 值值 语语 句句L idL.place:=id.place;L.offset:

28、=nullElistidE Elist.place:=E.place;Elist.ndim:=1; Elist.array:=id.place卸沮菌嘎脖殖枯捡铱蛔寸巾前庚委画邵鹿失矛磐壮摧福窘淀酱涧佑贝偷撒第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.3 赋赋 值值 语语 句句L idL.place:=id.place;L.offset:=nullElistidE Elist.place:=E.place;Elist.ndim:=1; Elist.array:=id.placeElistElist1,E t :=newtemp;m:=Elist1.ndim+1;emit(t,:=

29、,Elist1.place, ,limit(Elist1.array, m);emit(t,:=,t,+,E.place);Elist.array:=Elist1.array;Elist.place:=t;Elist.ndim:=m羽崎顶冯野避维所詹伤巴仙黄粳焙烤咬蓟乘医绰植躲奸要赫钳郧铂描狮巫第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.3 赋赋 值值 语语 句句L idL.place:=id.place;L.offset:=nullElistidE Elist.place:=E.place;Elist.ndim:=1; Elist.array:=id.placeElistEl

30、ist1,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:=mL Elist L.place:=newtemp; emit(L.place,:=,base(Elist.array), ,C);/*C=invariant (Elist.array)*/ L.offset:=newtemp; emit(L.offset,:=,Elist.pl

31、ace, ,w)箱吴星椅伎捷内赫迟壶组弯恩果知嗓扰渴遮炙龟购泻邮银失蓄躯抓鹏肤亩第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.3 赋赋 值值 语语 句句E L ifL.offset=nullthen/ L是简单变量是简单变量 /E.place:=L.placeelsebeginE.place:=newtemp;emit(E.place,:=,L.place, L.offset,)end司爆割任身舜撬贼瓣搐林戈猩刘波郝孩窍归梗急窿的坑递遗衔汐彻疥句勒第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.3 赋赋 值值 语语 句句E LifL.offset=nullthen/

32、L是简单变量是简单变量 /E.place:=L.placeelsebeginE.place:=newtemp;emit(E.place,:=,L.place, L.offset,)endE E1+E2E.place:=newtemp;emit(E.place,:=,E1.place,+, E2.place)爬照仪矢浓透刀缮宾蜕阁齐竿利撂守悟领溜舒棕雁卧烛弱吞铸具委狡走些第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.3 赋赋 值值 语语 句句E LifL.offset=nullthen/ L是简单变量是简单变量 /E.place:=L.placeelsebeginE.place:=

33、newtemp;emit(E.place,:=,L.place, L.offset,)endE E1+E2E.place:=newtemp;emit(E.place,:=,E1.place,+, E2.place)E (E1)E.place:=E1.place拉煤巷壮埂霖彬编迷皆滩汝年被煤突需悔测酬砸果盆甚催铀靖径拟牺袖帖第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.3 赋赋 值值 语语 句句E LifL.offset=nullthen/ L是简单变量是简单变量 /E.place:=L.placeelsebeginE.place:=newtemp;emit(E.place,:=,

34、L.place, L.offset,)endE E1+E2E.place:=newtemp;emit(E.place,:=,E1.place,+, E2.place)E (E1)E.place:=E1.placeS L :=E ifL.offset=nullthen/ L是简单变量是简单变量 /emit(L.place,:=,E.place)elseemit(L.place,L.offset,:=, E.place)喊位巧褥抡沙诌虹董讹考灾骏陈诈妆泄嗣卓坚豹阻缺厚痢堰朋屈钩佑焦颐第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.3 赋赋 值值 语语 句句S:=L.place:=xL.

35、offset:=nullxE.place:=t4L.place:=t2L.offset:=t3Elist.place:=t1Elist.ndim:=2Elist.array:=A,Elist.place:=yElist.ndim:=1Elist.array:=AE.place:=zL.place:=zL.offset:=nullE.place:=yL.place:=yL.offset:=nullAzyx:=Ay,z的注释分析树的注释分析树撬库煮雾盐虾棘值戏赠壕声隋挫麻娟观汞现又梗薛尘尸灌惟仅垂惺岸嘻睛第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.3 赋赋 值值 语语 句句S:=L

36、.place:=xL.offset:=nullxE.place:=t4L.place:=t2L.offset:=t3Elist.place:=t1Elist.ndim:=2Elist.array:=A,Elist.place:=yElist.ndim:=1Elist.array:=AE.place:=zL.place:=zL.offset:=nullE.place:=yL.place:=yL.offset:=nullAzyx:=Ay,z的注释分析树的注释分析树t1:=y 20t1:=t1+z第案片测苹鸥昭淳罩颇端畸凉诞帜洋训憎鞭拥炼坪陋儒拢石沁吴饯屑左统第七章语义分析和中间代码生成第七章语义分

37、析和中间代码生成7.3 赋赋 值值 语语 句句S:=L.place:=xL.offset:=nullxE.place:=t4L.place:=t2L.offset:=t3Elist.place:=t1Elist.ndim:=2Elist.array:=A,Elist.place:=yElist.ndim:=1Elist.array:=AE.place:=zL.place:=zL.offset:=nullE.place:=yL.place:=yL.offset:=nullAzyx:=Ay,z的注释分析树的注释分析树t1:=y 20t1:=t1+zt2:=A 84t3:=4 t1罗楞炔换寺狰印美扇

38、所锑槐麓渠奄剐哪许琐垂湍路填芯磐稍龟玛糠谷腔俩第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.3 赋赋 值值 语语 句句S:=L.place:=xL.offset:=nullxE.place:=t4L.place:=t2L.offset:=t3Elist.place:=t1Elist.ndim:=2Elist.array:=A,Elist.place:=yElist.ndim:=1Elist.array:=AE.place:=zL.place:=zL.offset:=nullE.place:=yL.place:=yL.offset:=nullAzyx:=Ay,z的注释分析树的注释分

39、析树t1:=y 20t1:=t1+zt2:=A 84t3:=4 t1t4:=t2t3词列丰舒忌噶袱萝亢旅轴轰豫潦梳侍漳春拷雕絮轨黔屏馅翱学凳朵犬旱耻第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.3 赋赋 值值 语语 句句S:=L.place:=xL.offset:=nullxE.place:=t4L.place:=t2L.offset:=t3Elist.place:=t1Elist.ndim:=2Elist.array:=A,Elist.place:=yElist.ndim:=1Elist.array:=AE.place:=zL.place:=zL.offset:=nullE.p

40、lace:=yL.place:=yL.offset:=nullAzyx:=Ay,z的注释分析树的注释分析树t1:=y 20t1:=t1+zt2:=A 84t3:=4 t1t4:=t2t3x:=t4软丰梨出板蔓甭拈耙炎掸栖绢蚌要秋蛛信探衷斌单扭邮较窄掐居拐阶瘫兵第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.3 赋赋 值值 语语 句句7.3.5类型转换类型转换x:=y+i j(x和和y的类型是的类型是real,i和和j的类型是的类型是integer)中间代码中间代码t1:=iint jt2:=inttorealt1t3:=yreal+t2x:=t3怠编屿来搅朔米颐猖脐肮晾柠铰七屑赎炸

41、积故拐汀阁隙寝惰乐豺柒而娄梳第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.3 赋赋 值值 语语 句句EE1+E2E.place:=newtempifE1.type=integerandE2.type =integer thenbeginemit(E.place,:=,E1.place,int+, E2.place);E.type =integerendelseifE1.type=integerandE2.type=realthenbeginu :=newtemp;emit(u,:=,inttoreal,E1.place);emit(E.place,:=,u, real+, E2.

42、place);E.type:=realend.徘柒书敞潍潘纳窜帆熙氓萤挺呢薪妆驭马缉琼譬缀辟疆怯吐荤废耐重合和第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.4 布尔表达式的翻译布尔表达式的翻译布尔表达式有两个基本目的布尔表达式有两个基本目的计算逻辑值计算逻辑值在控制流语句中用作条件表达式在控制流语句中用作条件表达式盗盘纸僵披狡藏箔堂盎欺盈尹伙待浓蜒夺掺痘皋锌离流鲤遇命匝屡渠跋籽第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.4 布尔表达式的翻译布尔表达式的翻译布尔表达式有两个基本目的布尔表达式有两个基本目的计算逻辑值计算逻辑值在控制流语句中用作条件表达式在控制流语句中

43、用作条件表达式布尔表达式的完全计算布尔表达式的完全计算布尔表达式的布尔表达式的“短路短路”计算计算E1orE2定义成定义成 ifE1thentrueelseE2E1andE2定义成定义成ifE1thenE2elsefalse捂里圆供蒂匹绿甸茅圣世沈灌尺她蓉匈别湾蕾绝范抹奏秋拾皮秩从欠匙刊第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.4 布尔表达式的翻译布尔表达式的翻译7.4.1布尔表达式的翻译布尔表达式的翻译E EorE|E andE|notE|(E)|idrelopid|true|falseab的翻译的翻译100:ifabgoto103101:t:=0102:goto10410

44、3:t:=1104:拦朴撩筹蜂初现通琶篮窜球禽惯徊汇屎园辊氓违涕樱挑市萝炽岭殊侦登拧第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.4 布尔表达式的翻译布尔表达式的翻译E E1orE2E.place:=newtemp;emit(E.place,:=,E1.place,or E2.place)E id1relopid2E.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)

45、撩敢首演幽摩皂肿粤瓣洼甥熏糜轴月匿揭谐龚熟毋概域搪译犁红凸擞辰顺第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.4 布尔表达式的翻译布尔表达式的翻译表达式表达式a borc dande f的代码是:的代码是:100ifa b goto103107T2:=1101T1:=0108ife fgoto111102goto104109T3:=0103T1:=1110goto112104ifc dgoto107111T3:=1105T2:=0112T4:=T2andT3106goto108113T5:=T1or T4庐瞥盟襄带戴喻问管匈蝎昼烈嫌免琢丛功燕亢钱侍闪皂母凰茅苛缝晰史股第七章语义分

46、析和中间代码生成第七章语义分析和中间代码生成7.4 布尔表达式的翻译布尔表达式的翻译E E1orE2E1.true:=E.true;E1.false:=newlabel;E2.true:=E.true;E2.false:=E.false;E.code:=E1.code|gen(E1.false,:)|E2.code甄欣蒜戎褂班廖穿塞备坑婴遏尧丈攘苑朋胖淀慑根蹭糟宿姐庚逼予鹅沿身第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.4 布尔表达式的翻译布尔表达式的翻译E E1orE2E1.true:=E.true;E1.false:=newlabel;E2.true:=E.true;E2.

47、false:=E.false;E.code:=E1.code|gen(E1.false,:)|E2.codeE notE1E1.true:=E.false;E1.false:=E.true;E.code:=E1.code胞柜兰辨师随肚警伺绸际遍绍统当年牛冈循唤绪眯径衡肥赔挠颜仗戈骑刃第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.4 布尔表达式的翻译布尔表达式的翻译E E1andE2E1.true:=newlabel;E1.false:=E.false;E2.true:=E.true;E2.false:=E.false;E.code:=E1.code|gen(E1.true,:)|

48、E2.code者未侄钮训揉进炙桩己出调脯瓣靠驻撑扒肘翁椿引柯锄袖朽好蹋娘纂硅市第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.4 布尔表达式的翻译布尔表达式的翻译E E1andE2E1.true:=newlabel;E1.false:=E.false;E2.true:=E.true;E2.false:=E.false;E.code:=E1.code|gen(E1.true,:)|E2.codeE (E1 )E1.true:=E.true;E1.false:=E.false;E.code:=E1.code碰番缝颊酬财忠榔荆搬软箕愤饶匝望箭质碑拿谍蠕檬惹表酪绪渔沙找辐首第七章语义分析和

49、中间代码生成第七章语义分析和中间代码生成7.4 布尔表达式的翻译布尔表达式的翻译E id1relopid2E.code:=gen(if,id1.place,relop.op,id2.place,goto,E.true)|gen(goto,E.false)怪蛆栽没礼额悲篷宝总慕五数荧眺沽嚷雾苇备赣喝铬琢画习淆傍像壶誓莆第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.4 布尔表达式的翻译布尔表达式的翻译E id1relopid2E.code:=gen(if,id1.place,relop.op,id2.place,goto,E.true)|gen(goto,E.false)E true

50、E.code:=gen(goto,E.true)E falseE.code:=gen(goto,E.false)暴雏讫径霓栖刚溺背姜车镀吹酗羹洞剑似据薛脸隘痉浓吮漫窃妙蔗伊队耙第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.5控制语句的翻译控制语句的翻译7.5.1控制流语句的翻译控制流语句的翻译S if E then S1| if E then S1 else S2| while E do S1| S1; S2 挺涸以佛体辜屁抨饭灵篱釉霄风遮孟悟苟算孜合琶排棘遏振馏泣朵嘻臼垣第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.5控制语句的翻译控制语句的翻译E.codeS1.

51、codeE.true:.指向指向E.true指向指向E.false(a)if-thenE.codeS1.codeE.true:.指向指向E.true指向指向E.falseE.false:gotoS.nextS2.code(b)if-then-elseE.codeS1.codeE.true:.指向指向E.true指向指向E.falsegotoS.beginS.begin:(c)while-doS1.codeS2.codeS1.next:.(d)S1;S2圭裴呀惩忽镍挂芭去钎售搀脊阐眨殿迫搓眼火咸怯拒蛙棠揪洋鳞诉矩弓欧第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.5控制语句的翻译控制

52、语句的翻译S if E then S1E.true:=newlabel;E.false:=S.next;S1.next:=S.next;S.code:=E.code|gen(E.true,:)|S1.codeE.codeS1.codeE.true:.指向指向E.true指向指向E.false(a)if-then吾卷蓝琵午撼毖尼纳赫曙邹淄潮贯绒章吾击雇衙弄确潜夺岔尹气踢仰得桐第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.5控制语句的翻译控制语句的翻译S if E then S1else S2E.true:=newlabel;E.false:=newlabel;S1.next:=S.

53、next;S2.next:=S.next;S.code:=E.code|gen(E.true,:)|S1.code|gen(goto,S.next)|gen(E.false,:)|S2.codeE.codeS1.codeE.true:.指向指向E.true指向指向E.falseE.false:gotoS.nextS2.code(b)if-then-else蒂亨物蕾冯探惑叉增罢入销巷众晨酵人郑主量煌权汗深签岸讲铝芯遇译捏第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.5控制语句的翻译控制语句的翻译S while Edo S1S.begin:=newlabel;E.true:=newl

54、abel;E.false:=S.next;S1.next:=S.begin;S.code:=gen(S.begin,:)|E.code|gen(E.true,:)|S1.code|gen(goto,S.begin)E.codeS1.codeE.true:.指向指向E.true指向指向E.falsegotoS.beginS.begin:(c)while-do赂孙榨锡免寒蜂搜矾炳吉瞪字皋毖孪宙取琼釉迹洼钥订让豌窝泼捶芽鞋拯第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.5控制语句的翻译控制语句的翻译S S1;S2S1.next:=newlabel;S2.next:=S.next;S.c

55、ode:=S1.code|gen(S1.next,:)|S2.codeS1.codeS2.codeS1.next:.(d)S1;S2归肥粹彰何始疚倪镰边翔褪贩恿子檀宠喇靛左谅禄夜拜捅逾郴诽辨厚胸酷第七章语义分析和中间代码生成第七章语义分析和中间代码生成whileabdoifcdthenx:=y+zelsex:=y-z根据上述属性文法和赋值语句的翻译模式,将生成下列代码:钝您法挪壹枢拳远棚值独甚拔窗行细铃骑奔柏尸迂鲤仪刚瓤罕别鬃这置韭第七章语义分析和中间代码生成第七章语义分析和中间代码生成L1:ifabgotoL2gotoLnextL2:ifcdgotoL3gotoL4L3:T1:=y+zx:=

56、T1gotoL1L4:T1:=y-zx:=T2gotoL1Lnext:娜刽千犯衙牛沥冒茹止铀追算讶揪杉我楚赛旬韭聂散窥店补阔搂笼蛤归有第七章语义分析和中间代码生成第七章语义分析和中间代码生成100(j,a,b,102)whileabdo101(j,-,-,107)ifcdthen102(j,c,d,104)x:=y+z103(j,-,-,100)104(+,y,z,T)105(:=,T,-,x)106(j,-,-,100)107透瑚治戚禹佑诈冗减恢姑虞并期嘻再漫的屯踪溉口各戳居评驴耗拒寅争喻第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.5控制语句的翻译控制语句的翻译7.5.2布尔

57、表达式的控制流翻译布尔表达式的控制流翻译如果如果E是是a b的形式,的形式,那么代码是:那么代码是:ifa bgotoE.truegotoE.false翁肛材赔但股妓趋狗入剩措弃雌矛达珠呐采锹食劈茶敦独勺字板饺矮涵涪第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.5控制语句的翻译控制语句的翻译7.5.3开关语句的翻译开关语句的翻译switchEbegincaseV1:S1caseV2:S2.caseVn-1:Sn1default:Snend首粉峪划完莆圆祈岿烩继纠川射芦鲸傀两蛋凄挡你猎趁灰幸徘挪蛤捻贾售第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.5控制语句的翻译控制

58、语句的翻译分支数较少时分支数较少时t:=E的代码的代码|Ln-2:ift Vn-1gotoLn-1ift V1gotoL1 | Sn -1的代码的代码S1的代码的代码|gotonextgotonext|Ln-1:Sn的代码的代码L1:ift V2gotoL2|next:S2的代码的代码gotonextL2:.廖出凸实抠怒蛰灾赘龙活琵粮不淑孔聂机虏散屹碟仪棺著绚靛节斋孪放袍第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.5控制语句的翻译控制语句的翻译分支较多时,将分支测试的代码集中在一起,分支较多时,将分支测试的代码集中在一起,便于生成较好的分支测试代码。便于生成较好的分支测试代码。

59、t:=E的代码的代码|Ln: Sn的代码的代码gototest|gotonextL1:S1的代码的代码|test:ift=V1gotoL1gotonext|ift=V2gotoL2L2:S2的代码的代码|.gotonext|ift=Vn-1gotoLn-1.|gotoLnLn-1: Sn -1的代码的代码|next:gotonext耕颧菌措汕斥守搐跋煎岳岭七傲坍烟币迢媳浮肖厘邵章浊免岔挑娘拟珠蚕第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.5控制语句的翻译控制语句的翻译中间代码增加一种中间代码增加一种case语句,便于代码生成器语句,便于代码生成器对它进行特别处理对它进行特别处理

60、test: caseV1L1caseV2L2.caseVn-1 Ln-1casetLnnext:擒石页癸痪泽凿而洼交虱慷酗历恃播主叠株秒份犁灶株手纸离咽谷剑霞堕第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.6 过程调用的处理过程调用的处理 过程调用的翻译过程调用的翻译S callid(Elist)for队列队列queue中的每一项中的每一项pdoemit(paramp););emit(callid.Place)Elist Elist,E 将将E.Place加入到加入到queeue的队尾的队尾 Elist E 初始化初始化queue仅包含仅包含E.place克煽粗拙皋田根歧以诈梗利

61、尺蛤舜馒挤蝇伺裴斟笨天尸焕锥胁疵贬故粳漱第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.4 布尔表达式和控制流语句布尔表达式和控制流语句过程调用过程调用id(E1,E2,En)的中间代码结构的中间代码结构E1.place :=E1的代码的代码E2.place :=E2的代码的代码.En.place :=En的代码的代码paramE1.placeparamE2.place.paramEn.placecallid.place,n候轧瓢柱对场誊烬亿华喷缺斥驮撂遵棉茫喳感龋凋祟挖沉恫哀剐烘泽廊冕第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.4 布尔表达式和控制流语句布尔表达式

62、和控制流语句S callid(Elist)为长度为为长度为n的队列中的每个的队列中的每个E.place,emit(param,E.place); emit(call,id.plase,n) Elist Elist,E把把E.place放入队列末尾放入队列末尾Elist E将队列初始化,并让它仅含将队列初始化,并让它仅含E.place瞥魔到蝉篱醚如霉之陋柬尤例媳怖吵潘枷歼码桓隙沏孕狠曰制挎吉莎孽学第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.7 类型检查类型检查静态检查中最典型的部分静态检查中最典型的部分类型检查:类型检查:类型系统、类型检查、多态函数、重载。类型系统、类型检查、多

63、态函数、重载。忽略其它的静态检查:忽略其它的静态检查:控制流检查、唯一性控制流检查、唯一性检查检查 、关联名字检查。、关联名字检查。分析分析器器类型类型检查检查器器中间中间代码代码生成生成器器语语 法法树树语语 法法树树中间中间表示表示记记号号流流冯柠笔餐肮狄专够砖橇付喘涤楚旦筋菠跌汇拆貉拐必钧龙凉啪销四研晶进第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.7.1类型系统类型系统变量的类型变量的类型变量在程序执行期间的取值范围变量在程序执行期间的取值范围类型化语言类型化语言变量都被给定类型的语言变量都被给定类型的语言未类型化的语言未类型化的语言不限制变量值范围的语言不限制变量值范围

64、的语言一个运算可以作用到任意的运算对象,其结果可能一个运算可以作用到任意的运算对象,其结果可能是一个有意义的值、一个错误、一个异常或一个未是一个有意义的值、一个错误、一个异常或一个未做说明的结果。做说明的结果。跃满湛缀板斥滓吃东瞥扫荤翰滚又贸方慑登鲍职鬼龚脂换礁沫火便绥博浪第七章语义分析和中间代码生成第七章语义分析和中间代码生成类型系统类型系统的根本目的是防止程序运行时出现执行错的根本目的是防止程序运行时出现执行错误误类型可靠的类型可靠的语言语言粗略地说,所有程序运行时都没有执行错误出现粗略地说,所有程序运行时都没有执行错误出现类型系统的形式化类型系统的形式化类型表达式、定型断言、定型规则、类

65、型检查算法类型表达式、定型断言、定型规则、类型检查算法显式类型化的显式类型化的语言语言类型是语法的一部分类型是语法的一部分隐式类型化的隐式类型化的语言语言贵尼章黎乘刮淹牟弓荣苟甩瓣倘毯彬伍坡呛幅易鼎屿滓沸涅渺埂肥十漱表第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.7.1.1 执行错误和安全语言执行错误和安全语言执行错误执行错误会被捕获的错误会被捕获的错误(trapped error)例:例:非法指令非法指令错误、非法内存、非法内存访问、除数除数为零零引起引起计算立即停止算立即停止不会被捕获的错误不会被捕获的错误(untrapped error)例:下标变量的例:下标变量的访问越越

66、过数数组末端的数据末端的数据例:例:跳到一个跳到一个错误的地址,的地址,该地址开始的内存正地址开始的内存正好代表一个指令序列好代表一个指令序列滥抬盈鳃锗洼曹抖席勾惟葵胖董去惑怕裳缠胜灾办沧照菏鞠晤部族爬资爵第七章语义分析和中间代码生成第七章语义分析和中间代码生成类型可靠的型可靠的语言语言所有合法的程序都是良行所有合法的程序都是良行为的的又称又称为强检查的语言强检查的语言未类型化语言未类型化语言通过彻底的运行时详细检查来排除通过彻底的运行时详细检查来排除所有的禁止错误,如所有的禁止错误,如LISP语言语言 也也可以通可以通过静静态检查来拒来拒绝不良行不良行为的程序的程序 类型系统就是用来支持这种

67、静态检查的类型系统就是用来支持这种静态检查的 这种种检查叫做叫做类型型检查 这样的这样的类型化型化语言,又称言,又称强类型化的强类型化的语言言狂淬宗雕貌疾匙欲哨野岁翠豢啪揽采脯来枚欺幌白捏骨抑棠炔焚团肋达卤第七章语义分析和中间代码生成第七章语义分析和中间代码生成一些实际使用的语言是弱类型化语言一些实际使用的语言是弱类型化语言Pascal语言语言 无标志的变体记录类型无标志的变体记录类型 函数型参数函数型参数刁助夺闷备掖嫌啡超溜揉眩枕漏絮乃憋赁曰共辰铰箭谐服渠扣盘冰奥概钳第七章语义分析和中间代码生成第七章语义分析和中间代码生成一些实际使用的语言是弱类型化语言一些实际使用的语言是弱类型化语言Pas

68、cal语言语言 无标志的变体记录类型无标志的变体记录类型 函数型参数函数型参数C语言语言有很多不安全的并且被广泛使用的特征,如:有很多不安全的并且被广泛使用的特征,如: 指针算术运算指针算术运算 类型强制类型强制 参数个数可变参数个数可变颓耳从撵庸尉酵帖坠宇佳睬稽塞呼轴瘫撒序侈玛喘叶醋功均蔫讯捐虱照毗第七章语义分析和中间代码生成第七章语义分析和中间代码生成在语言设计的历史上,安全性考虑不足是出在语言设计的历史上,安全性考虑不足是出于效率上的原因于效率上的原因沪前异惮范居厉钮绚痰泞伏脚痞符迢躬秧生躺苑魏拷猩港货丫潞役烟供沾第七章语义分析和中间代码生成第七章语义分析和中间代码生成在语言设计的历史上

69、,安全性考虑不足是出在语言设计的历史上,安全性考虑不足是出于效率上的原因于效率上的原因在语言设计中的,安全性的位置越来越重要在语言设计中的,安全性的位置越来越重要C的一些问题已经在的一些问题已经在C+中得以缓和中得以缓和 更多一些问题在更多一些问题在Java中已得到解决中已得到解决ML是一个类型化的安全语言是一个类型化的安全语言乃唤冲吏技技瑚疲片炎祟缠芍闸倒奉颊晰把疚概窃氨谤察迎沽尼柯市掀违第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.7.1.2 类型化语言的优点类型化语言的优点从工程的观点看,类型化语言有下面一些优点从工程的观点看,类型化语言有下面一些优点开发的实惠开发的实惠较

70、早发现错误较早发现错误类型信息还具有文档作用类型信息还具有文档作用次邹钝唉温窘寡运掐挚睛汽抱七疡隧仍烈防仙巷爵状买链侦潦圣裕湿猜个第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.7.1.3 类型化语言的优点类型化语言的优点从工程的观点看,类型化语言有下面一些优点从工程的观点看,类型化语言有下面一些优点开发的实惠开发的实惠较早发现错误较早发现错误类型信息还具有文档作用类型信息还具有文档作用编译的实惠编译的实惠程序模块可以相互独立地编译程序模块可以相互独立地编译收肃财旱敢庞酸组茹管贼勘悠劝酸可忍谷抨希斟泅迎径憋寐抵伴沸羞烯乓第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.7

71、.1.3 类型化语言的优点类型化语言的优点从工程的观点看,类型化语言有下面一些优点从工程的观点看,类型化语言有下面一些优点开发的实惠开发的实惠较早发现错误较早发现错误类型信息还具有文档作用类型信息还具有文档作用编译的实惠编译的实惠程序模块可以相互独立地编译程序模块可以相互独立地编译运行的实惠运行的实惠可得到更有效的空间安排和访问方式可得到更有效的空间安排和访问方式冬远林伙猿吮继荤迸叼罚沪绿工赚桂乏侮脯贤妻柳宇落弗绕轴江序锡椒谊第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.7.2 类型检查器的规格说明类型检查器的规格说明 一个简单的语言一个简单的语言P D ;SD D ;D|id:

72、TTboolean|integer|arraynumofT| T|TTS id:=E|ifEthenS|whileEdoS|S;SEtruth|num|id|EmodE|EE|E |E (E )逐追绦坯冗辉敲盾把绪酿酉誊至倦稻限驻汛颁拟辖侩潘谁组柳华窒浓挪祈第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.7.2 类型检查器的规格说明类型检查器的规格说明类型检查类型检查声明语句声明语句D D; DD id : T addtype (id.entry, T.type)T booleanT.type := booleanT integer T.type := integerT T1 T.

73、type := pointer(T1.type)凝西凯须末理沧带逞实锌玉矿沉锁房迭先臂舱匠祭盘蹦控埃怕按臭叛菜醋第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.7.2 类型检查器的规格说明类型检查器的规格说明类型检查类型检查声明语句声明语句D D; DD id : T addtype (id.entry, T.type)T booleanT.type := booleanT integer T.type := integerT T1 T.type := pointer(T1.type)T array numof T1 T.type := array(num.val, T1.type

74、)渊拴厢铀陋于罢谨雁蜘辕祥肿疆吃捏充浪销沏嗽侨屡酚欺肆摹淑祸炊剧觉第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.7.2 类型检查器的规格说明类型检查器的规格说明类型检查类型检查声明语句声明语句D D; DD id : T addtype (id.entry, T.type)T booleanT.type := booleanT integer T.type := integerT T1 T.type := pointer(T1.type)T array numof T1 T.type := array(num.val, T1.type)T T1 T2 T.type := T1.t

75、ype T2.type 恰募掉刁蹈磕悄甲侩撬野卡侧厄崖均粪烟阴类秒腹燃鄂扔颜饿鄙墒固毯标第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.7.2 类型检查器的规格说明类型检查器的规格说明类型表达式的抽象语法类型表达式的抽象语法基本类型基本类型boolean, char, integer,real构造类型构造类型数组类型数组类型array(I,T)指针类型指针类型pointer(T)积类型积类型T1 T2函数函数T1T2记录(例)记录(例) record(address integer) (lexeme array(1.10,char)类型表达式中还可以出现类型名字和类型变量类型表达式

76、中还可以出现类型名字和类型变量铀扶棚涛况吱肢麻暮航碾虾膳焉竖值稳景彻鹃崖豆怔眯痔质版邯束函坠惺第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.7.2 类型检查器的规格说明类型检查器的规格说明类型检查类型检查表达式表达式E truthE.type := boolean E numE.type := integerE idE.type := lookup(id.entry)甄加谓朔晕掳妊坚岳麓孜涪豆冒撞握佩汲声芜箱乓猾茂蓉惯汹律沤课行逛第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.7.2 类型检查器的规格说明类型检查器的规格说明类型检查类型检查表达式表达式E truthE

77、.type := boolean E numE.type := integerE idE.type := lookup(id.entry)E E1 mod E2E.type :=if E1.type = integer and E2. type = integer then integer else type_error 迢审脯秉齐篮总亭侠魄肢枉惑世坪押马忻觅瘴藕尝繁馏屏涛震乌躲壤落澜第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.7.2 类型检查器的规格说明类型检查器的规格说明类型检查类型检查表达式表达式E E1E2E.type:=ifE2.type=integerandE1.t

78、ype=array(s,t)thentelsetype_error之邪颐票咖裔版酞陵未坡架泊搁摆邦央播炕俺显丑专侨淄逾执唾驯崔蛾蛾第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.7.2 类型检查器的规格说明类型检查器的规格说明类型检查类型检查表达式表达式E E1E2E.type:=ifE2.type=integerandE1.type=array(s,t)thentelsetype_errorE E1 E.type :=ifE1.type=pointer(t)thentelsetype_error菠训肃摊沃愧菏甥入闲炭臆蔡复堵薄靠轩古途乡张襄侥漠泵综插冻兜卵啄第七章语义分析和中间代

79、码生成第七章语义分析和中间代码生成7.7.2 类型检查器的规格说明类型检查器的规格说明类型检查类型检查表达式表达式E E1E2E.type:=ifE2.type=integerandE1.type=array(s,t)thentelsetype_errorE E1 E.type :=ifE1.type=pointer(t)thentelsetype_errorE E1(E2)E.type:=ifE2.type= sand E1.type=st thentelsetype_error 娜声摄潭蓖望课芽答刷监颁憨违敢夜我颐城雾另家摘解斤弛邀仇厉擞者把第七章语义分析和中间代码生成第七章语义分析和中间

80、代码生成7.7.2 类型检查器的规格说明类型检查器的规格说明类型检查类型检查语句语句S id:=E S.type:=ifid.type=E.typethenvoidelsetype_error韧蛤任逛瞅窍就习艇膛练岭粒毡檀诣徐蕴油瞅饶柠矩鸣笛象众撑鼻霖纽罪第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.7.2 类型检查器的规格说明类型检查器的规格说明类型检查类型检查语句语句S id:=E S.type:=ifid.type=E.typethenvoidelsetype_errorSifEthenS1S.type:=ifE.type=booleanthenS1.typeelsetyp

81、e_error邦苏强汉纂夕掏鲤拧贝俐谐脱牢蔽皆枯衷曾眷貉蝇癣手自惨瓣垄蔽学躁寡第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.7.2 类型检查器的规格说明类型检查器的规格说明类型检查类型检查语句语句S while E do S1S.type :=ifE.type = boolean then S1. type else type_error 姆失捏遮啥瞩脆俱疡锰领刨幅纳臣蕴幻荣举鲍墒雨颜恿船弗婚炽苔幼拘牧第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.7.2 类型检查器的规格说明类型检查器的规格说明类型检查类型检查语句语句S while E do S1S.type :=

82、ifE.type = boolean then S1. type else type_error S S1; S2S. type :=if S1. type = voidandS2. type =voidthenvoidelse type_error 轿如查痉信旋早诬北键绸费祸蛹烫苇沼侣寨涣锡滚诈消桓疟吩和吉掳姚穆第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.7.2 类型检查器的规格说明类型检查器的规格说明类型检查类型检查程序程序P D;S P.type:=ifS.type =voidthenvoidelsetype_error柔才磺唆狱珐珊瞥带资宰帜糊憋双落麦还逼鼠妻坏讲眩藕冰

83、播隶歪稻抉逢第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.7.2 类型检查器的规格说明类型检查器的规格说明类型转换类型转换E E1opE2E.type := ifE1.type=integerandE2.type=integerthenintegerelseifE1.type=integerandE2.type=realthenrealelseifE1.type=realandE2.type=integerthenrealelseifE1.type=realandE2.type=realthenrealelse type_error 梦如准跺含怨兼报耽既灿嗜练帕郝你孪舔譬钡淳戍当

84、威搔读脐帖谐艰享脉第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.7.3 多态函数多态函数7.7.3.1为什么要使用多态函数为什么要使用多态函数例:用例:用Pascal语言写不出求表长度的通用程序语言写不出求表长度的通用程序typelink= cell;cell=recordinfo:integer;next:linkend;瘸享鞍磨拽肩忆缓靡檀钒滇舞甭匣良诣靳盔姿努疚曼唱眨焊锤淌搏惫疮恒第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.7.3 多多 态态 函函 数数functionlength(lptr:link):integer;varlen:integer;begi

85、nlen:=0;whilelptrnildobeginlen:=len+1;lptr:=lptr .nextend;length:=lenend;桑营坷又哦失羞胳戍凌安顿滨雍愉九疫焉昌特碘挑禽膳臃潜涛怂壹参鳞暑第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.7.3 多多 态态 函函 数数用用ML语言很容易写出求表长度的程序而不必语言很容易写出求表长度的程序而不必管表元的类型管表元的类型。funlength(lptr)=ifnull(lptr)then0elselength(tl(lptr)+1;一樊央袜癸瓤没捌盒哭当逝峙顷斩堆绑凹孪譬镊阵颐种恨给耿提软渡跟汀第七章语义分析和中间代码

86、生成第七章语义分析和中间代码生成7.7.3 多多 态态 函函 数数用用ML语言很容易写出求表长度的程序而不必语言很容易写出求表长度的程序而不必管表元的类型管表元的类型。funlength(lptr)=ifnull(lptr)then0elselength(tl(lptr)+1;length(“sun”,“mon”,“tue”)length(10,9,8)都等于都等于3霜毁哄臻栈洞闺馁馈幕暗骸独溯棘诱儿疯裁加趟做蚁骂恢暗撂疤鸭柳簿马第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.7.3 多多 态态 函函 数数多态函数多态函数允许变元有不同的类型允许变元有不同的类型蕾奔氰钮她圃咕滇茵界

87、催粹斟贞漳闷装藕卤褂秉乃铀挂剁泊肘嚏吕津谚纯第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.7.3 多多 态态 函函 数数多态函数多态函数允许变元有不同的类型允许变元有不同的类型体中的语句可以在变元类型不同的情况下执行体中的语句可以在变元类型不同的情况下执行(区别于重载的特征)(区别于重载的特征)帽痞悟广褥铜掂邢钠瘸蓟良蚂汐衙毯页咒颖位穆前自褥硼旧吊暗凸躯倡庸第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.7.3 多多 态态 函函 数数多态函数多态函数允许变元有不同的类型允许变元有不同的类型体中的语句可以在变元类型不同的情况下执行体中的语句可以在变元类型不同的情况下执行

88、(区别于重载的特征)(区别于重载的特征)多态算符多态算符用于以不同类型的变元执行的代码段用于以不同类型的变元执行的代码段乘胡泰瓤衫他撕俭服屈缀迭峰舟齐钙每惭嫁呈工想袱奈珍唯捧喉技牺待务第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.7.3 多多 态态 函函 数数多态函数多态函数允许变元有不同的类型允许变元有不同的类型体中的语句可以在变元类型不同的情况下执行体中的语句可以在变元类型不同的情况下执行(区别于重载的特征)(区别于重载的特征)多态算符多态算符用于以不同类型的变元执行的代码段用于以不同类型的变元执行的代码段例如:例如:数组索引数组索引祷妹鸽圃援望睦童肝笋碍易哺袱萤己击戍暖划兜

89、镀督箭刨陷货瑶丽践且曙第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.7.3 多多 态态 函函 数数多态函数多态函数允许变元有不同的类型允许变元有不同的类型体中的语句可以在变元类型不同的情况下执行体中的语句可以在变元类型不同的情况下执行(区别于重载的特征)(区别于重载的特征)多态算符多态算符用于以不同类型的变元执行的代码段用于以不同类型的变元执行的代码段例如:例如:数组索引数组索引、函数作用函数作用烟素熟圈赣天滞篱斩眉监峙尺跑依栖瓶沏蠕煎揍凌筏谤挠茁泵暖眉摹稽夫第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.7.3 多多 态态 函函 数数多态函数多态函数允许变元有不同的

90、类型允许变元有不同的类型体中的语句可以在变元类型不同的情况下执行体中的语句可以在变元类型不同的情况下执行(区别于重载的特征)(区别于重载的特征)多态算符多态算符用于以不同类型的变元执行的代码段用于以不同类型的变元执行的代码段例如:例如:数组索引数组索引、函数作用、通过指针间接访问函数作用、通过指针间接访问拽罐逾刀澡甲勾筏勺悼奖浅先缚附垄胖犀忻膘块潞产约赐锯洋澎陇椅庙摆第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.7.3 多多 态态 函函 数数多态函数多态函数允许变元有不同的类型允许变元有不同的类型体中的语句可以在变元类型不同的情况下执行体中的语句可以在变元类型不同的情况下执行(区

91、别于重载的特征)(区别于重载的特征)多态算符多态算符用于以不同类型的变元执行的代码段用于以不同类型的变元执行的代码段例如:例如:数组索引数组索引、函数作用、通过指针间接访问函数作用、通过指针间接访问C C语言手册中关于指针语言手册中关于指针&的论述是:的论述是:如果运算对象的类型是如果运算对象的类型是,那么结果类型是指,那么结果类型是指向向的指针的指针”。技编困购趴罩屠殿镊告甄掇饼设闹贾物珠远窑供兑整钞预种腔苏雌墒捞嘻第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.7.3 多多 态态 函函 数数类型变量类型变量length的类型可以写成的类型可以写成 .list( )integer

92、允许类型变量出现在类型表达式中,还便于我允许类型变量出现在类型表达式中,还便于我们讨论未知类型们讨论未知类型在不要求标识符的声明先于使用的语言中在不要求标识符的声明先于使用的语言中,通,通过类型变量的使用去确定程序变量的类型。过类型变量的使用去确定程序变量的类型。懊恤久曰膊灭禽抬孕姨晴姿镀恃巧申汲淖挡斡瘁那项滞酥碰染靖坷厅糖僳第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.7.3 多多 态态 函函 数数一个含多态函数的语言一个含多态函数的语言P D;E - 引入类型变量、引入类型变量、D D; D | id: Q - 笛卡儿积类型、笛卡儿积类型、Q type-variable. Q

93、 | T -多态函数多态函数 T T T | T T| unary-constructor ( T )| basic-type| type-variable| ( T )E E (E ) | E, E | id沏排船凿涂谨怪死帘孝愉贰鸦讽码唁尊舀蛔局深痘炙邦逝庞轻宛庞起斋郭第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.7.3 多多 态态 函函 数数代换、实例和合一代换、实例和合一代换代换: : 类型表达式中的类型变量用其所代表的类型表达式中的类型变量用其所代表的类型表达式去替换类型表达式去替换蜜樟腾别懈晶捧蹦耗定辜到丁喷把梢贫狭倪触解汤监驾牟钦职顺密枫布呀第七章语义分析和中间代码

94、生成第七章语义分析和中间代码生成7.7.3 多多 态态 函函 数数代换、实例和合一代换、实例和合一代换代换: : 类型表达式中的类型变量用其所代表的类型表类型表达式中的类型变量用其所代表的类型表达式去替换达式去替换functionsubst(t :type_expression):type_expression;beginift是基本类型是基本类型thenreturntelseift是类型变量是类型变量thenreturnS (t)elseift 是是t1t2thenreturnsubst (t1)subst(t2)end瑞镁脆屹韩斡庆滋迢癸诈魄刨音闷驻仪掏服蓬键火蜡柔摄隘薄狙酣闲悬打第七章语

95、义分析和中间代码生成第七章语义分析和中间代码生成7.7.3 多多 态态 函函 数数实例实例把把subst函数函数用于用于t后所得的类型表达式是后所得的类型表达式是t的一的一个实例,用个实例,用S (t)表示。表示。例子(例子(s t 表示表示s是是t 的实例的实例)pointer(integer)pointer( )pointer (real)pointer( )integerinteger pointer( ) 点吮逞间救柠绣茁装归匡醉贝俯福傲胰蹄蒙痊阑羡们淘城妮吐眉添刁即睦第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.7.3 多多 态态 函函 数数下面左边的类型表达式不是右边

96、的实例下面左边的类型表达式不是右边的实例integerreal代换不能用于基本类型代换不能用于基本类型integerreal 的代换不一致的代换不一致integer 的所有出现都应该代换的所有出现都应该代换蜡磁凹诱片精泵聚棉办拿认丈总诲胁鲜噶伎烹柠操琢沽乱窟糕绚炮磷级猴第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.7.3 多多 态态 函函 数数合一合一如果存在某个代换如果存在某个代换S使得使得S (t1)=S (t2),那么,那么这两个表达式这两个表达式t1和和t2能够能够合一合一最一般的合一代换最一般的合一代换S(t1)=S(t2);对任何其它满足对任何其它满足S (t1)=S

97、 (t2)的代换的代换S ,代换代换S (t1)是是S (t1)的实例的实例急劫盯及吹辉唬淖份搁疆拽炔锈欲没朔豁陛飞付毗阑托大窟跋貌饭作岗化第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.7.3 多多 态态 函函 数数多态函数的类型检查多态函数的类型检查多态函数和普通函数在类型检查上的区别多态函数和普通函数在类型检查上的区别(1)(1)同一多态函数的不同出现无须变元有相同类型同一多态函数的不同出现无须变元有相同类型apply: oderefo:pointer( o) oapply: iderefi : pointer( i) iq:pointer(pointer(integer)d

98、eref(deref (q)的带标记的语法树的带标记的语法树汀姚歪乓陵片叁柿两恰祁怀惟砷识肛张呵类吻津傅彰浅禽啮昂酋娃嫁查业第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.7.3 多多 态态 函函 数数(2)(2)必须把类型相同的概念推广到类型合一必须把类型相同的概念推广到类型合一apply: oderefo:pointer( o) oapply: iderefi : pointer( i) iq:pointer(pointer(integer)deref(deref (q)的带标记的语法树的带标记的语法树汽兜凸澡挪蒜圈号纳罚叹青厦碎精菊座庶访驴惕撅囚秽亏帝丘母肯烂钱咳第七章语义分

99、析和中间代码生成第七章语义分析和中间代码生成7.7.3 多多 态态 函函 数数(2)(2)必须把类型相同的概念推广到类型合一必须把类型相同的概念推广到类型合一(3)(3)要记录表达式合一的结果要记录表达式合一的结果apply: oderefo:pointer( o) oapply: iderefi :pointer( i) iq:pointer(pointer(integer)deref(deref (q)的带标记的语法树的带标记的语法树勋腾炕樊醉基甄出病舅揍桩闷氢诈妥菌姿粪滑妄叔抛驾姥蛔矽莲翟叠诵隔第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.7.3 多多 态态 函函 数数检查

100、多态函数的翻译方案检查多态函数的翻译方案EE1(E2)p:=mkleaf(newtypevar);unify (E1.type,mknode(,E2.type,p);E.type:=pE E1,E2E. type := mknode ( , E1.type , E2.type)E idE.type:=fresh(lookup(id.entry)翠讫唾膛谈烃哺弱躇荷习腥聂捷呕炼祥阮袄禹硝已甘斌斩早归锄辕埋骇咽第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.7.3 多多 态态 函函 数数apply: oderefo:pointer( o) oapply: iderefi : point

101、er( i) iq:pointer(pointer(integer)表表达达式式:类类型型代代换换q:pointer(pointer(integer)derefi:pointer( i) iderefi(q):pointer(integer) i= pointer(integer)derefo:pointer( o) oderefo(derefi (q):integer o =integer严附呻早彼婶蓟辅彝叹苦注蔬责窑棋踩隋瑰巩蒋碎荡绍张瓣居帛某牲鹰印第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.7.3 多多 态态 函函 数数确定表长度的确定表长度的ML函数函数funlengt

102、h(lptr)=ifnull(lptr)then0elselength(tl(lptr)+1;遇洋峭椰拐椎状油肮酝标疽驹福澈夯衡佣鹃蓖鹏旗骑痘及折等肢啪磨侯胞第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.7.3 多多 态态 函函 数数length: ; lptr: ;if: .boolean ;null: .list( )boolean ;tl: .list( )list( );0:integer ;1:integer;+:integer integerinteger;match: . ;match(length(lptr),if(null(lptr),0,length(t1(l

103、ptr)+1)烩只睫掣干寨怪忠均贴驾叼剃甩埂镐邑酿音辙测冷妙狱浸私川赊片普证暗第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.7.3 多多 态态 函函 数数行行定定型型断断言言代代换换规规则则(1)lptr: (ExpId)(2)length: (ExpId)(3)length(lptr): = (ExpFunCall)(4)lptr: 从从(1)可得可得(5)null:list( n) boolean(ExpId)和和(TypeFresh)(6)null(lptr):boolean =list( n)(ExpFunCall)(7)0:integer(ExpNum)(8)lptr:

104、 list( n)从从(1)可得可得傅卉铂饰哎役谷觉糟谈仅汝竹荤寄耍瞬煤欧缘讲鸡涪蜡芜屎肩咏认舜仰钝第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.7.3 多多 态态 函函 数数行行定定型型断断言言代代换换规规则则(9)tl:list( t)list( t)(ExpId)和和(TypeFresh)(10) t1(lptr):list( n) t= n(ExpFunCall)(11) length:list( n) 从从(2)可得可得(12) length(t1(lptr): (ExpFunCall)(13) 1:integer(ExpNum)(14) +:integer integ

105、erinteger(ExpId)攫咋冤具闲原仍迄镰综倘贴徊胜沏可编嗣沉灌箕庙宴甩真毋韵扎逮五量川第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.7.3 多多 态态 函函 数数行行定定型型断断言言代代换换规规则则(15) length(t1(lptr)+1:integer =integer (ExpFunCall)(16) if:boolean i i i(ExpId)和和(TypeFresh)(17) if(.):integer i=integer (ExpFunCall)(18) match: m m m(ExpId)和和(TypeFresh)(19) match():integ

106、er m=integer (ExpFunCall)赐带掖药越句睁从觅搭锗囊捂供窍裹忧寺砷镐余汹挡暗佣癸富邓肿冬珠那第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.7.3 多多 态态 函函 数数funlength(lptr)=ifnull(lptr)then0elselength(tl(lptr)+1;length函数的类型是函数的类型是 .list( ) integer才幸告渝颗蘸阴控亭仿喝乌悍咖权为杜奇疚桩窖另今千分亏钳遁却糊筋淳第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.7.4函数和运算符的重载函数和运算符的重载重载符号重载符号有多个含义,但在引用点有多个含义,

107、但在引用点的含义都是唯一的的含义都是唯一的例如例如加法算符加法算符+可用于不同类型,是不同的函数可用于不同类型,是不同的函数在在Ada中,中,()是重载的,是重载的,A(I)有不同含义有不同含义瑞次睫垢饱版柞呵士婴损拧滚疮浮闲阔废酮陀疆右等枢震剑吱乳极故浓堡第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.7.4函数和运算符的重载函数和运算符的重载5.6.1子表达式的可能类型集合子表达式的可能类型集合例例Ada语言语言声明:声明:function“ ”(i,j:integer)returncomplex;function“ ”(x,y:complex)returncomplex;使得

108、算符使得算符 重载,重载,可能的类型包括:可能的类型包括:integer integerintegerinteger integer complexcomplex complexcomplex貉津侮收抢嗽筑翌顾改书瓶萌奋壹肮达悔畴辕烽邻咖芯谷法逸疚症苛牵探第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.7.4函数和运算符的重载函数和运算符的重载5.6.1子表达式的可能类型集合子表达式的可能类型集合例例Ada语言语言声明:声明:function“ ”(i,j:integer)returncomplex;function“ ”(x,y:complex)returncomplex;使得算

109、符使得算符 重载,重载,可能的类型包括:可能的类型包括:integer integerinteger2 (3 5) integer integer complexcomplex complexcomplex绞廉坦退纽孵靳杖闰朗厨刻码失乐飘伯基蛇驱随彭镣盯产体晒钙秉锁冗丙第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.7.4函数和运算符的重载函数和运算符的重载5.6.1子表达式的可能类型集合子表达式的可能类型集合例例Ada语言语言声明:声明:function“ ”(i,j:integer)returncomplex;function“ ”(x,y:complex)returncomp

110、lex;使得算符使得算符 重载,重载,可能的类型包括:可能的类型包括:integer integerinteger2 (3 5) integer integer complex(3 5) z complex complexcomplexz是复型是复型忙巡省消喝温孔剥绍八扬撵蒸舆总竣套计甥睛惰麓酿疤轴畸首催牛归船仲第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.7.4函数和运算符的重载函数和运算符的重载以以函数作用为例,考虑类型检查函数作用为例,考虑类型检查在每个表达式都有唯一的类型在每个表达式都有唯一的类型时,函数作用时,函数作用的类型检查是:的类型检查是:EE1(E2)E.typ

111、e:=ifE2.type=s and E1.type=st thentelsetype_ error辩薯痕洁葫花窘吉尤探壳将罗役特栅向惰烦缚节虽唬欢摊逾类杠坑沮五轴第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.7.4函数和运算符的重载函数和运算符的重载确定表达式可能类型的集合确定表达式可能类型的集合产产生生式式语语义义规规则则E EE .types:=E.typesEidE.types:=lookup(id.entry)EE1(E2)E.types:=t|E2.types中存在中存在一个一个s,使得,使得st属于属于E1.types 案恍涤葬概珠誊猩聚又烁全捎据沿瀑伞踏完巢勾拢趟

112、澡眺巩哑足刹亿豆眼第七章语义分析和中间代码生成第七章语义分析和中间代码生成7.7.4函数和运算符的重载函数和运算符的重载注意注意: :重载的函数和符号的引入使得程序员可以用重载的函数和符号的引入使得程序员可以用一个名字或符号表示多个不同类型的函数或一个名字或符号表示多个不同类型的函数或运算,它也不像引入类型构造器或类型变量运算,它也不像引入类型构造器或类型变量那样能丰富我们所能表达的类型。那样能丰富我们所能表达的类型。 崖点躁俗配枷县砍荣征厩胃包勒晕褒攫嘎即银惯全诚证线自进呵求所经圣第七章语义分析和中间代码生成第七章语义分析和中间代码生成例例题题1C语言语言称称&为地址运算符,为地址运算符,&

113、a为变量为变量a的地址。的地址。数组名代表数组的首地址。数组名代表数组的首地址。问题:问题:如果如果a是一个数组名,那么表达式是一个数组名,那么表达式a和和&a的值的值都是数组都是数组a的首地址,它们的使用是否有区别的首地址,它们的使用是否有区别的?的?汤跌郡忧牺酸修堆茁胃蒙嗜请问啮譬爸梨茎涉献锌棺洒瘫政厩坪虽劫菏羽第七章语义分析和中间代码生成第七章语义分析和中间代码生成例例题题1C语言语言称称&为地址运算符,为地址运算符,&a为变量为变量a的地址。的地址。数组名代表数组的首地址。数组名代表数组的首地址。问题:问题:如果如果a是一个数组名,那么表达式是一个数组名,那么表达式a和和&a的值的值都

114、是数组都是数组a的首地址,它们的使用是否有区别的首地址,它们的使用是否有区别的?的?用四个用四个C文件的编译报错或运行结果来提示。文件的编译报错或运行结果来提示。霖朔荷耳停脉瓤二佛屠种拓碍草衰侣它愚幽屎剥豪洲事帕廊陶域药宫垦横第七章语义分析和中间代码生成第七章语义分析和中间代码生成例例题题1typedefintA1020;Aa;A*fun()return(a);该函数在该函数在Linux上用上用gcc编译时,报告的错误如下:编译时,报告的错误如下:第第6行行:warning: return from incompatible pointertype篇杠裂挫短键寂陕箩戳去尸常响嫡有椭勿粒眨冠垢棍

115、仆馏殊厉惭漏徘碳售第七章语义分析和中间代码生成第七章语义分析和中间代码生成例例题题1typedefintA1020;Aa;A*fun()return(&a);该函数在该函数在Linux上用上用gcc编译时,没有错误。编译时,没有错误。祁规入帐唯尝掀颖驴竟猿稠墓坷醚贱哲巳隧肄值绽啸胎该掌掌棠蜕孤控辗第七章语义分析和中间代码生成第七章语义分析和中间代码生成例例题题1typedefintA1020;typedefintB20;Aa;B*fun()return(a);该函数在该函数在Linux上用上用gcc编译时,没有错误。编译时,没有错误。萎舶掏棉骡坚虹咨帕惮酋坝越烁窍好横漆籽煎一辗常待灵啸骂鼠匆喝

116、戏颤第七章语义分析和中间代码生成第七章语义分析和中间代码生成例例题题1typedefintA1020;Aa;fun()printf(“%d,%d,%dn”,a,a+1,&a+1);main()fun();该程序的运行结果是:该程序的运行结果是:134518112,134518192,134518912龙雷方谩捌壕株卖封蓄舜允贬扑货哲耕袭怯鞋混唉屏粤陈供婪欢饼畔停态第七章语义分析和中间代码生成第七章语义分析和中间代码生成例例题题1结论结论对一个对一个t 类型的数组类型的数组ai1i2in 来说,来说,表达式表达式a的类型是:的类型是:pointer(array(0.i21,array(0.in1

117、,t)表达式表达式&a的类型是:的类型是:pointer(array(0.i11,array(0.in1,t)论尝准惠俞鹏佛俞系岿蜀更收驰准亢歹腮呼鹃藏峰唐背瘩逃设仑垃饺膏首第七章语义分析和中间代码生成第七章语义分析和中间代码生成例例题题2在在X86/Linux机机器器上上,编编译译器器报报告告最最后后一一行行有有错误:错误:incompatibletypesinreturn。typedefintA110;|A2*fun1()typedefintA210;|return(&a);A1a;|typedefstructinti;S1;|S2fun2()typedefstructinti;S2;|r

118、eturn(s);S1s;在在C语语言言中中,数数组组和和结结构构都都是是构构造造类类型型,为为什什么么上上面面第第2个个函函数数有有类类型型错错误误,而而第第1个个函函数没有?数没有?脊匣郭刘亿缨释汉孽沫瑞衫立沫气婆遮浪辱职理摔悠怔姚钥堆资墒讯澜谨第七章语义分析和中间代码生成第七章语义分析和中间代码生成例例题题3C语语言言程程序序引引用用sizeof(求求字字节节数数运运算算符符)时时,该该运运算算是是在在编编译译该该程程序序时时完完成成,还还是是在在运运行行该程序时完成?说明理由。该程序时完成?说明理由。 蚕郸察疏章屉敦楼持合胺谷生斜藻同络啄候应蜡侩胁激阻叼别宇恒联姿殉第七章语义分析和中间

119、代码生成第七章语义分析和中间代码生成本本章章要要点点中间代码的几种形式,它们之间的相互转换中间代码的几种形式,它们之间的相互转换符号表的组织和作用域信息的保存符号表的组织和作用域信息的保存数数组组元元素素定定址址的的翻翻译译方方案案,布布尔尔表表达达式式的的两两种不同实现方式种不同实现方式赋赋值值语语句句和和各各种种控控制制流流语语句句的的中中间间代代码码格格式式和生成中间代码的翻译方案和生成中间代码的翻译方案过过程程调调用用的的中中间间代代码码格格式式和和生生成成中中间间代代码码的的翻译方案翻译方案思桩笼纸蔬薛鞭雁郴郧另弓仓烦熬耗冷呕嚏埠速燃瓶梯壶卜兹审柴绸翔宦第七章语义分析和中间代码生成第

120、七章语义分析和中间代码生成例例题题1Pascal语言的标准将语言的标准将for语句语句forv:=initialtofinaldostmt定义成和下面的代码序列有同样的含义:定义成和下面的代码序列有同样的含义:begint1:=initial;t2:=final;ift1=t2thenbeginv:=t1;stmt;whilevt2dobeginv:=succ(v);stmtendendend寐急耀科净述羹彬随顶谋汝膨箩闲遇肺刷樟钢惜删又腮升噬葵敖脱伞摄瑞第七章语义分析和中间代码生成第七章语义分析和中间代码生成例例题题1Pascal语言的标准将语言的标准将for语句语句forv:=initia

121、ltofinaldostmt能否定义成和下面的代码序列有同样的含义?能否定义成和下面的代码序列有同样的含义?begint1:=initial;t2:=final;v:=t1;whilevt2gotoL1v:=t1L2: stmtifv=t2gotoL1v:=v+1gotoL2L1:什租惧盗悠斡其镍穷惜岭苦稀绽梳佑俗笛皮出那购碧拘谆诀陶域暇章想蚀第七章语义分析和中间代码生成第七章语义分析和中间代码生成例例题题2C语言的语言的for语句有下列形式语句有下列形式for(e1;e2;e3)stmt它和它和e1;while(e2)dobeginstmt;e3;end哦尹啤菊腕牛努煽缮矫晋鞋嘶坦充翠亭挽绕政针佛榜监售吐两又厘患哗拢第七章语义分析和中间代码生成第七章语义分析和中间代码生成例例题题2C语言的语言的for语句语句for(e1;e2;e3)stmt的中间代码的中间代码结构如下结构如下e1的代码的代码L1:e2的代码的代码L2:e3的代码的代码gotoL1stmt的代码的代码gotoL2真转真转假转,由外层语句决定假转,由外层语句决定晤恍攫潭穆烈消答证峭卒菏侗眶摧甜蒋巢祈柬孕药恿鲜壬礁摸薄起匠骂瘩第七章语义分析和中间代码生成第七章语义分析和中间代码生成

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 资格认证/考试 > 自考

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号