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

    编译原理第2版第二章PL-0编译程序.ppt

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

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

    编译原理第2版第二章PL-0编译程序.ppt

    第2章 PL/0编译程序,本章目的:以PL/0编译程序为实例,学习编译程序实现的基本步骤和相关技术1 PL/0编译程序的结构2 PL/0编译程序的分析工作(词法,语法和语义)实现3 PL/0编译程序的错误处理方法4 目标代码生成和类pcode代码解释器,1.PL/0编译程序的结构,PL/0编译程序,PL/0 语言程序,类 pcode 代码,源语言(PL/0)目标语言(类 pcode)实现语言(pascal/C),PL/0,类 pcode,pascal/C,PL/0编译程序,类 pcode解释程序,类 pcode代码,PL/0源程序,输入数据,输出数据,PL/0编译系统的结构框架,PL/0语言,PL/0语言:PASCAL语言的子集 PL/0程序示例 PL/0的语法描述图 PL/0语言的EBNF表示,PL/0程序示例,CONST A=10;(*常量说明部分*)VAR B,C;(*变量说明部分*)PROCEDURE P;(*过程说明部分*)VAR D;(*P的局部变量说明部分*)PROCEDURE Q;(*P的局部过程说明部分*)VAR X;BEGIN READ(X);D:=X;WHILE X#0 DO CALL P;END;BEGIN WRITE(D);CALL Q;END;BEGIN CALL P;END.,Q过程体,p过程体,主程序体,输入圆柱的半径和高,计算一些面积、体积等,var r,h,len,a1,a2,volumn;beginread(r);read(h);len:=2*3*r;a1:=3*r*r;a2:=a1+a1+len*h;volumn:=a1*h;write(len);write(a1);write(a2);write(volumn);end.,计算最大公约数,var m,n,r,q;计算m和n的最大公约数 procedure gcd;begin while r#0 do begin q:=m/n;r:=m-q*n;m:=n;n:=r;endend;,begin read(m);read(n);为了方便,规定m=n if m n then begin r:=m;m:=n;n:=r;end;begin r:=1;call gcd;write(m);end;end.,pl/0程序-递规调用,var n;procedure rec;begin if n#0 then begin write(n);n:=n-1;call rec;end;end;begin read(n);call rec;end.,计算 sum=1!+2!+.+n!,n从控制台读入,var n,m,fact,sum;递规计算 fact=m!procedure factorial;begin if m 0 then begin fact:=fact*m;m:=m-1;call factorial;end;end;,begin 读入n read(n);sum:=0;while n 0 do begin m:=n;fact:=1;call factorial;sum:=sum+fact;n:=n-1;end;输出n!write(sum);end.,程序,分程序,.,内的文字表示语法成分(短语),或,内的文字表示单词符号,程序,.,内的文字表示语法成分(短语),语法图,const,ident,number,var,ident,procedure,ident,分程序,语句,分程序,PL/0语言的EBNF表示,构成EBNF的元素(非终结符,终结符,开始符,规则)EBNF 的元符号:用左右尖括号括起来的内容为非终结符=读做定义为=的左部由右部定义 读做定义为 的左部由右部定义|读做或 表示右部候选内容 表示花括号内的内容可重复任意次或限 定次数 表示方括号内的内容为任选项()表示圆括号内的内容优先,例:用EBNF描述的定义:=+|-=0|1|2|3|4|5|6|7|8|9 或=+|-|0=1|2|3|4|5|6|7|8|9=0|,PL/0语言是PASCAL语言的子集,同PASCAL 作用域规则(内层可引用包围它的外层定义的标识符),上下文约束,过程可嵌套定义,可递归调用子集数据类型,只有整型数据结构,只有简变和常数数字最多为14位标识符的有效长度是10语句种类过程无参,最多可嵌套三层,目标代码类p-code,目标代码类p-code是一种栈式机的汇编语言。栈式机系统结构:没有累加器和寄存器,只有存储栈指针 所有运算都在栈顶(零地址机)指令格式:,f l a,f功能码l层次差(标识符引用层减去定义层)a根据不同的指令有所区别,指令功能表,const a=10;var b,c;procedure p;begin c:=b+a;end;begin read(b);while b#0 do begin call p;write(2*c);read(b);endend.,(0)jmp 0 8 转向主程序入口(1)jmp 0 2 转向过程p入口(2)int 0 3 过程p入口,为过程p开辟空间(3)lod 1 3 取变量b的值到栈顶(4)lit 0 10 取常数10到栈顶(5)opr 0 2 次栈顶与栈顶相加(6)sto 1 4 栈顶值送变量c中(7)opr 0 0 退栈并返回调用点(16)(8)int 0 5 主程序入口开辟5个栈空间(9)opr 0 16 从命令行读入值置于栈顶(10)sto 0 3 将栈顶值存入变量b中(11)lod 0 3 将变量b的值取至栈顶(12)lit 0 0 将常数值0进栈(13)opr 0 9 次栈顶与栈顶是否不等(14)jpc 0 24 等时转(24)(条件不满足转)(15)cal 0 2 调用过程p(16)lit 0 2 常数值2进栈(17)lod 0 4 将变量c的值取至栈顶(18)opr 0 4 次栈顶与栈顶相乘(2*c)(19)opr 0 14 栈顶值输出至屏幕(20)opr 0 15 换行(21)opr 0 16 从命令行读取值到栈顶(22)sto 0 3 栈顶值送变量b中(23)jmp 0 11 无条件转到循环入口(11)(24)opr 0 0 结束退栈,PL/0编译程序的结构,词法分析程序,语法语义分析程序,代码生成程序,表格管理程序,出错处理程序,PL/0源程序,目标程序,PL/0编译程序的总体设计,以语法、语义分析程序为核心 词法分析程序和代码生成程序都作为一个过程,当语法分析需要读单词时就调用词法分析程序,而当语法、语义分析正确,需要生成相应的目标代码时,则调用代码生成程序。表格管理程序实现变量,常量和过程标识符的信息的登录与查找。出错处理程序,对词法和语法、语义分析遇到的错误给出在源程序中出错的位置和与错误 性质有关的编号,并进行错误恢复。,第2章 PL/0编译程序,本章目的:以PL/0编译程序为实例,学习编译程序实现的基本步骤和相关技术1 PL/0编译程序的结构2 PL/0编译程序的分析工作(词法,语法和语义)实现3 PL/0编译程序的错误处理方法4 目标代码生成和类pcode代码解释器,2 PL/0编译程序的分析工作(词法,语法和语义)2.1PL/0编译程序词法分析的实现,识别的单词:保留字或关键字:如:BEGIN、END、IF、THEN等运算符:如:+、-、*、/、:=、#、=、=等标识符:用户定义的变量名、常数名、过程名常数:如:10、25、100等整数界符:如:,、.、;、(、)等,词法分析过程GETSYM所要完成的任务:从源程序读字符(getch)滤空格识别保留字识别标识符拼数识别单字符单词拼双字符单词,词法分析过程:GETSYM框图(见教材图2.5)程序(procedure getsym)当识别到标识符时先查保留字表保留字表:(begin(*main*))word1:=begin;word2:=call;.word13:=write;查到时找到相应的内部表示Wsym1:=beginsym;wsym2:=callsym;wsym13:=writesym;,字符对应的单词表:ssym+:=plus;ssym-:=minus;ssym;:=semicolon;词法分析如何把单词传递给语法分析 type symbol=(nul,ident,number,plus,varsym,procsym);3个全程量 SYM:symbol;ID:alfa;NUM:integer;,通过三个全程量 SYM、ID和NUM 将识别出的单词信息传递给语法分析程序。SYM:存放单词的类别 如:有程序段落为:begin initial:=60;end 对应单词翻译后变为:begin beginsym,initial ident,:=becomes,60 number,;semicolon,end endsym。ID:存放用户所定义的标识符的值 如:initial(在SYM中放ident,在ID中放initial)NUM:存放用户定义的数 如:60(在SYM中放number,在NUM中放60),使用状态转换图实现词法分析程序的设计方法,词法分析程序的设计-使用状态转换图实现,表示状态,对应每个状态编一段程序,每个状态调用取字符程序,根据当前字符转到不同的状态,并做相应操作。,表示终态,已识别出一个单词。,2.2 PL/0编译程序语法分析,自顶向下的语法分析 递归子程序法,(上下文无关文法)句型的分析,句型分析就是识别一个符号串是否为某文法的句型的过程,或者说是某个推导的构造过程。对于一个给定的文法,要想判定一个符号串是否为该文法的句子,需要考察是否可以从该文法的开始符号派生出(推导出)此符号串。编译程序的语法分析工作。,分析算法分类,分析算法可分为:自上而下分析法:从文法的开始符号出发,寻找与输入符号串匹配的推导,或者说,为输入串寻找一个最左推导。自下而上分析法:从输入符号串开始,逐步进行归约,直至归约到文法的开始符号。,语法分析(从概念上讲)建立一棵与输入串相匹配的语法树。语法树推导的几何表示,句型aabbaa的可能推导序列和语法树,例:GS:SaASASbAASSSaAba,S a A S S b A a a b a,SaASaAaaSbAaaSbbaaaabbaaSaASaSbASaabASaabbaSaabbaaSaASaSbASaSbAaaabAaaabbaa,两种方法反映了语法树的两种构造过程。,自上而下方法是从文法符号开始,将它做为语法树的根,向下逐步建立语法树,使语法树的结果正好是输入符号串自下而上方法则是从输入符号串开始,以它做为语法树的结果,自底向上的构造语法树,自上而下的语法分析的一般过程,例:文法G:S cAd A ab A a识别输入串w=cabd是否为该文法的句子,SSScAdcAd a b推导过程:S cAd cAd cabd,程序,分程序,.,const,ident,number,var,ident,procedure,ident,分程序,语句,分程序,ident,read,end,语句,表达式,:=,begin,语句,语句,),(,ident,自顶向下的语法分析,VAR A;BEGIN READ(A)END.,.VAR;A BEGIN END READ()A,为文法的开始符号,以开始符号作为根结点构造一棵倒挂着的语法树。,递归子程序法-语法分析程序由一组递归过程组成,对应每个非终结符(语法单元),编一个独立的处理过程(或函数,子程序)。由(即开始符)开始,沿语法描述图箭头所指出的方向进行分析(规则右部)遇到非终结符(进入了又一个语法单元),则调用相应的处理过程 遇到终结符,则判断当前读入的单词是否与该终结符相匹配,若匹配,再读取下一个单词继续分析。也称为递归下降分析器(recursive-descent parser),例:表达式的语法分析程序(递归子程序),项,表达式,+,-,项,+,-,项,因子,因子,*,/,语法图,因子的语法图,因子,ident,number,(,表达式,),表达式的EBNF表达式=+|-项(+|-)项项=因子(*|/)因子因子=标识符|无符号整数|(表达式),表达式=+|-项(+|-)项pascal,表达式的分析程序(递归子程序)procedure expr;begin if sym in plus,minus then begin getsym;term;end else term;while sym in plus,minus do begin getsym;term;endend;,项=因子(*|/)因子 pascal,项的分析程序(递归子程序)procedure term;begin factor;while sym in times,slash do begin getsym;factor;endend;,因子=标识符|无符号整数|(表达式),因子的分析程序(递归子程序)procedure factor;begin if sym ident then begin if sym number then begin if sym=(then begin getsym;expr;if sym=)then getsym else error end else error end else getsym end else getsym end;,表达式=+|-项(+|-)项 in C,int expression(bool*fsys,int*ptx,int lev)if(sym=plus|sym=minus)/*开头的正负号,当前表达式被看作一个正的或负的项*/getsymdo;termdo(nxtlev,ptx,lev);/*处理项*/else/*此时表达式被看作项的加减*/termdo(nxtlev,ptx,lev);/*处理项*/while(sym=plus|sym=minus)getsymdo;termdo(nxtlev,ptx,lev);/*处理项*/return 0;,项=因子(*|/)因子,int term(bool*fsys,int*ptx,int lev)factordo(nxtlev,ptx,lev);/*处理因子*/while(sym=times|sym=slash)getsymdo;factordo(nxtlev,ptx,lev);return 0;,因子=标识符|无符号整数|(表达式),int factor(bool*fsys,int*ptx,int lev)if(sym=ident)/*因子为常量或变量*/getsymdo;else if(sym=number)/*因子为*/getsymdo;else if(sym=lparen)/*因子为表达式*/expressiondo(nxtlev,ptx,lev);if(sym=rparen)getsymdo;else error(22);/*缺少右括号*/return 0;,=begin(*main*)(*initialize*)(*r/w file set*)getsym;block();if sym period then error.end.。,程序 pl0,分程序 block,语句 statement,条件 condition,表达式expression,项 term,因子 factor,语法调用关系图,编译系统总体流程图,2.3 PL/0编译程序语义分析的设计与实现,PL/0编译程序语法、语义分析的的核心程序是BLOCK过程哪些语义分析工作?如何实现?-语义分析环境(符号表)说明部分的分析与处理表格管理过程体(语句)的分析与处理,因子=标识符|无符号整数|(表达式),语义分析int factor(bool*fsys,int*ptx,int lev)if(sym=ident)/*因子为常量或变量*/i=position(id,*ptx);/*查找名字*/if(i=0)error(11);/*标识符未声明*/elseswitch(tablei.kind)case constant:/*名字为常量*/break;case variable:/*名字为变量*/break;case procedur:/*名字为过程*/error(21);/*不能为过程名*/,登录符号表说明部分的分析与处理,对每个过程(含主程序)说明的对象(变量,常量和过程)造符号表 登录标识符的属性。标识符的属性:种类,所在层次,值和分配的相对位置。登录信息由ENTER过程完成。,符号表结构,Enum object constant,variable,procedur;Struct tablestruct char nameal;enum object kind;int val;int level;int adr;int size;Struct tablestruct tabletxmax;,符号表结构,说明种类的定义:object=(constant,variable,procedur)(定义纯量/枚举类型)符号表的定义 table:array0.txmax of record name:alfa;case kind:object of constant:(val:integer);variable:procedur:(level,adr,size:integer);,例程序说明部分为:CONST A=35,B=49;VAR C,D,E;PROCEDURE P;VAR G;,符号表,名字 种类 层次/值 地址 存储空间,对应名字表,tx:table表的下标指针,是以值参数形式使用的。dx:计算每个变量在运行栈中相对本过程基地址的偏移量,放在table表中的adr域,生成目标代码时再放在code中的a域,变量定义语句的处理(C),语法::=var,;程序:if(sym=varsym)/*收到变量声明符号,开始处理变量声明*/getsymdo;do vardeclarationdo(注意:&tx,变量说明处理(C),int vardeclaration(int*ptx,int lev,int*pdx)if(sym=ident)enter(variable,ptx,lev,pdx);/填写名字表 getsymdo;else error(4);/*var后应是标识符*/return 0;,变量定义语句的处理,语法::=var,;程序:if sym=varsym then begin getsym;repeat vardeclaration;(*变量说明处理*)while sym=comma do begin getsym;vardeclaration end;if sym=semicolon then getsym else error(5)until symident;end;,变量说明处理,procedure vardeclaration;begin if sym=ident then begin enter(variable);getsym end else error(4)end(*vardeclaration*);,过程ENTER的实现(C),/*在名字表中加入一项*k:名字种类const,var or procedure*ptx:名字表尾指针的指针*lev:名字所在的层次,以后所有的lev都是这样*pdx:当前应分配变量的相对地址,分配后增加1*/void enter(enum object k,int*ptx,int lev,int*pdx),过程ENTER的实现(C),(*ptx)+;strcpy(table(*ptx).name,id);/*全局变量id中已存有当前名字的名字*/table(*ptx).kind=k;switch(k)case constant:/*常量名字*/if(num amax)error(31);/*数越界*/num=0;table(*ptx).val=num;break;,过程ENTER的实现(C),case variable:/*变量名字*/table(*ptx).level=lev;table(*ptx).adr=(*pdx);(*pdx)+;break;case procedur:/*过程名字*/table(*ptx).level=lev;break;,过程ENTER的实现,tx:table表的指针 procedure enter(k:object);begin(*enter object into table*)tx:=tx+1;with tabletx do(*开域语句*)begin name:=id;(*表示tabletx.name:=id;*)kind:=k;(*表示tabletx.kind:=k;*),过程ENTER的实现,case k of constant:begin if numamax then begin error(31);num:=0;end;val:=num;(*tabletx.val:=num;*)end;,过程ENTER的实现,variable:begin level:=lev;(*表示tabletx.level:=lev*)adr:=dx;(*表示tabletx.adr:=dx*)dx:=dx+1;end;procedur:level:=lev(*表示tabletx.level:=lev;*)end(*case*);endend(*enter*);,过程体的处理,/*编译程序主体*lev:当前分程序所在层*tx:名字表当前尾指针*fsys:当前模块后跟符号集合*/int block(int lev,int tx,bool*fsys),过程体的处理,./main()函数 if(-1=block(0,0,nxtlev).if(sym!=period)error(9);.interpret();/*调用解释执行程序*/.,过程体的处理,while(sym=procsym)/block()函数 getsymdo;if(sym=ident)enter(procedur,.if(-1=block(lev+1,tx,nxtlev),过程体的处理变量引用的处理,对语句进行语法分析语义分析 当遇到标识符的引用时就调用POSITION函数查TABLE表,看是否有过正确定义,若已有,则从表中取相应的有关信息,供代码的生成使用。若无定义则错。语义分析 TABLE表若已有过正确定义,检查引用与说明的属性是否一致,若不一致则错。当语法语义正确时,就生成相应语句功能的目标代码,赋值语句的处理(C),if(sym=ident)/*准备按照赋值语句处理*/i=position(id,*ptx);if(i=0)error(11);/*变量未找到*/else if(tablei.kind!=variable)error(12);/*赋值语句格式错误*/i=0;else.gendo(sto,lev-tablei.level,tablei.adr);.,赋值语句的处理,if sym=ident then begin i:=position(id);if i=0 then error(11)else if tablei.kind variable then begin error(12);i:=0 end;getsym;if sym=becomes then getsym else error(13);expression(fsys);if i 0 then with table i do gen(sto,lev-level,adr)end,第2章 PL/0编译程序,本章目的:以PL/0编译程序为实例,学习编译程序实现的基本步骤和相关技术1 PL/0编译程序的结构2 PL/0编译程序的分析工作(词法,语法和语义)实现3 PL/0编译程序的错误处理方法4 目标代码生成和类pcode代码解释器,编译程序的错误处理,错误处理的原则:尽可能准确指出出错位置,错误性质,尽可能进行校正。PL/0编译程序对语法错误的处理:(1)对于易于校正的错误,如丢了逗号,分号等,指出出错位置,加以校正,继续进行分析。(2)对于难于校正的错误,给出错误的位置与性质,跳过后面的一些单词,直到下一个可以进行正常语法分析的语法单位。,在进入某个语法单位时,调用TEST,检查当前符号是否属于该语法单位的开始符号集合。若不属于,则滤去开始符号和后跟符号集合外的所有符号。在语法单位分析结束时,调用TEST,检查当前符号是否属于调用该语法单位时应有的后跟符号集合。若不属于,则滤去后跟符号和开始符号集合外的所有符号。,TEST TEST,开始符号集合与后跟符号集合,开始符号集合 symset=set of symbol;declbegsys,statbegsys,facbegsys:symset;开始符号集合(*主程序*)declbegsys:=constsym,varsym,procsym;statbegsys:=beginsym,callsym,ifsym,whilesym,readsym,writesym;facbegsys:=ident,number,lparen;,后跟符号集合fsys作为参数:procedure test(s1,s2:symset;n:integer);procedure block(lev,tx:integer;fsys:symset);procedure statement(fsys:symset);procedure expression(fsys:symset);procedure term(fsys:symset);procedure factor(fsys:symset);,READ语句的分析处理(C),if(sym=readsym)/处理read语句 getsymdo;if(sym!=lparen)error(34);/格式错误,应是左括号 else do getsymdo;,READ语句的语法语义分析处理,if sym=readsym then begin getsym;if symlparen then error(34)else repeat getsym;,READ语句的语法语义分析处理,if sym=ident then i:=position(id)else i:=0;if i=0 then error(35)else with tablei do begin gen(opr,0,16);gen(sto,lev-level,adr)end;,READ语句的语法语义分析处理,getsym until symcomma;if symrparen then begin error(33);while not(sym in fsys)do getsym end else getsym end,出错处理跳过不应出现的符号,正确出口,TEST,SYM在S1中?,打印出错编号n,S1:=S1+S2,SYM在S1中?,GETSYM,返回,Y,Y,N,N,TEST测试过程流程图,因子的处理过程,例:因子的处理过程 procedure factor(fsys:symset);var i:integer;begin 入口:test(facbegsys,fsys,24);while sym in facbegsys do begin if.出口:test(fsys,facbegsys,23);end end;,因子的处理过程,Facbegsys,y,处理ident number,lparen,test,n,test,增加后跟符与调用位置有关 例:调用expression(fsys);write语句的语法write(,);write语句(后调用expression时后跟符 expression(rparen,comma+fsys);factor的语法:factor=.|(exp)在factor(后调用expression时后跟符 expression(rparen+fsys);,第2章 PL/0编译程序,本章目的:以PL/0编译程序为实例,学习编译程序实现的基本步骤和相关技术1 PL/0编译程序的结构2 PL/0编译程序的分析工作(词法,语法和语义)实现3 PL/0编译程序的错误处理方法4 目标代码生成和类pcode代码解释器,代码生成,代码生成是由过程GEN完成。GEN有3个参数,分别代表目标代码的功能码,层差和位移量。例如 gen(opr,0,16);gen(sto,lev-level,adr)lev:当前处理的过程层次 level:被引用变量或过程所在层次CX:为目标代码code数组的下标指针,代码结构变换,地址返填,If c then s getsym;condition;if sym=thensym then getsym else error(16);cx1:=cx;gen(jpc,0,0)statement();codecx1.a:=cx,类pcode代码解释器的实现,类pcode目标机结构目标代码解释执行时数据栈的布局(运行栈的存储分配),目标代码类p-code,目标代码类p-code是一种栈式机的汇编语言。栈式机系统结构:没有累加器和寄存器,只有存储栈指针 所有运算都在栈顶(零地址机)指令格式:,f l a,f功能码l层次差(标识符引用层减去定义层)a根据不同的指令有所区别,类pcode解释器的结构,目标代码(指令)存放在数组CODE中(程序地址寄存器p)。解释程序定义一个一维整型数组S作为运行栈栈顶寄存器(指针)t,基址寄存器(指针)b,指令寄存器i(当前正在解释的目标指令),const a=10;var b,c;procedure p;begin c:=b+a;end;begin read(b);while b#0 do begin call p;write(2*c);read(b);endend.,(0)jmp 0 8 转向主程序入口(1)jmp 0 2 转向过程p入口(2)int 0 3 过程p入口,为过程p开辟空间(3)lod 1 3 取变量b的值到栈顶(4)lit 0 10 取常数10到栈顶(5)opr 0 2 次栈顶与栈顶相加(6)sto 1 4 栈顶值送变量c中(7)opr 0 0 退栈并返回调用点(16)(8)int 0 5 主程序入口开辟5个栈空间(9)opr 0 16 从命令行读入值置于栈顶(10)sto 0 3 将栈顶值存入变量b中(11)lod 0 3 将变量b的值取至栈顶(12)lit 0 0 将常数值0进栈(13)opr 0 9 次栈顶与栈顶是否不等(14)jpc 0 24 等时转(24)(条件不满足转)(15)cal 0 2 调用过程p(16)lit 0 2 常数值2进栈(17)lod 0 4 将变量c的值取至栈顶(18)opr 0 4 次栈顶与栈顶相乘(2*c)(19)opr 0 14 栈顶值输出至屏幕(20)opr 0 15 换行(21)opr 0 16 从命令行读取值到栈顶(22)sto 0 3 栈顶值送变量b中(23)jmp 0 11 无条件转到循环入口(11)(24)opr 0 0 结束退栈,目标代码解释执行时数据栈的布局(运行栈的存储分配),在每个过程调用时在栈顶分配3个联系单元:SL:静态链,指向定义该过程的直接外过程(或主程序)运行时最新数据段的基地址。DL:动态链,指向调用该过程前正在运行过 程的数据段基地址。RA:返回地址,记录调用该过程时目标程序的断点,即调用过程指令的下一条指令的地址。,Var x,y;Procedure P;var a;procedure Q;var b;begin(*Q*)b:=10;end(*Q*);procedure S;var c,d;procedure R;var e,f;begin(*R*)call Q;end(*R*);,begin(*S*)call R;end(*S*);begin(*P*)call S;end;(*P*)begin(*MAIN*)call P;end(*MAIN*).,目标代码的解释执行 运行栈S,M调用过程P M调用过程P P调用过程S,RA DL SL,b,t,t,b,P,M,P,M,S,目标代码的解释执行,几条特殊指令在code中的位置和功能INT 0 A在过程目标程序的入口处,开辟A个单元的数据段。A为局部变量的个数+3。OPR 0 0在过程目标程序的出口处,释放数据段(退栈),恢复调用该过程前正在运行的过程的数据段基址寄存器B和栈顶寄存器T的值,并将返回地址送到指令地址寄存器P中,以使调用前的程序从断点开始继续执行。,目标代码的解释执行,几条特殊指令在code中的位置和功能CAL L A调用过程,还完成填写静态链、动态链、返回地址,给出被调用过程的基地址值,送入基址寄存器B中,目标程序的入口地址A的值送指令地址寄存器P中,使指令从A开始执行。,CX:为目标代码code数组的下标指针。code为一维数组,数组元素为记录型数据。每一个记录就是一条目标指令。CX 为整数变量,由0开始顺序增加。实际上目标代码的顺序是内层过程的在前边,主程序的目标代码在最后。tx:table表的下标指针,是以值参数形式使用的。dx:计算每个变量在运行栈中相对本过程基地址的偏移量,放在table表中的adr域,生成目标代码时再放在code中的a域。,下标指针cx,tx和变量dx的作用,code cx tabletx s t(运行栈)cx tx t(运行时栈指针),(0)jmp 0 0(1)int 0 7.(cx).,(0)name adr.(1)b(dx).(tx),q,p,m,b,Table表的下标指针tx补充说明:,主程序,BLOCK,第1次调用blockBLOCK(0,0,),0,0,.,BLOCK,BLOCK(LEV+1,TX,)(递归进入分程序),LEV,tx,LEV,tx,(6),6(9),1,tx是BLOCK的实际值参,PL/0编译程序的实现,procedure gen(x:fct;y,z:integer);begin if cxcxmax then(*指针越界*)begin write(program too long);close(fin);(*关闭文件*)writeln;exit end;,PL/0编译程序的实现,with codecx do begin f:=x;(*表示codecx.f:=x;*)l:=y;(*表示codecx.l:=y;*)a:=z;(*表示codecx.a:=z;*)end;cx:=cx+1end(*gen*);,PL/0编译程序的实现,对分程序的定义(见教材417,437页)procedure block(lev,tx:integer;fsys:symset);var dx:integer;(*data allocationindex*)tx0:integer;(*initial table index*)cx0:integer;(*initial code index*)(tx0,cx0是tx,cx的初值),PL/0编译程序的实现,对分程序体人口的处理(见程序文本block 的过程体)begin(*block*)dx:=3;tx0:=tx;(保留当前table表指针值)tabletx.adr:=cx;(保留当前code指针值到过程名 的adr域)gen(jmp,0,0);(生成转向过程体入口的指令,该指令的地址 为cx 已保留在过程名的adr域,等生成 过程 体入口的指令时,再由tabletx.adr中取出 cx将过程体入口返填到cx中,即(jmp,0,0)的第3区域。(注意dx,tx,cx的作用),CONST A=35,B=49;VAR C,D,E;PROCEDURE P;VAR G,table表格管理,名字 类型 层次/值 地址 存储空间,(0)jmp 0 0 CX(1)jmp 0 0.,记录 过程在code的入口到table中的adr域,PL/0编译程序的

    注意事项

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

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




    备案号:宁ICP备20000045号-2

    经营许可证:宁B2-20210002

    宁公网安备 64010402000987号

    三一办公
    收起
    展开