PL0 编译程序讲解-文档资料_第1页
PL0 编译程序讲解-文档资料_第2页
PL0 编译程序讲解-文档资料_第3页
PL0 编译程序讲解-文档资料_第4页
PL0 编译程序讲解-文档资料_第5页
已阅读5页,还剩55页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、1第二章第二章 PL/0PL/0编译程序的实现编译程序的实现本章以本章以PL/0PL/0编译程序编译程序为实例为实例, , 使大家对编译程序的实现建立起整体概念,对编译程序的构造得到一些感性认识和初步了解。1 PL/0PL/0语言语言2 PL/0PL/0处理机处理机假想栈式机假想栈式机3 PL/0PL/0编译程序编译程序4 4 符号表的一般形式讨论符号表的一般形式讨论5 5 栈式存储管理的再讨论栈式存储管理的再讨论21 PL/0PL/0语言语言PL/0PL/0功能简单、结构清晰、可读性强,而又具备了一功能简单、结构清晰、可读性强,而又具备了一般高级语言的必备部分,因而其编译程序能充分体般高级语

2、言的必备部分,因而其编译程序能充分体现一个高级语言编译程序的基本技术和步骤。现一个高级语言编译程序的基本技术和步骤。zPL/0PL/0语言:语言:PASCALPASCAL语言的语言的子集,用于教学子集,用于教学zPL/0PL/0程序示例程序示例zPL/0PL/0的的语法描述图语法描述图zPL/0PL/0语言语言的的EBNFEBNF表示表示3 PL/0PL/0语言是语言是PASCALPASCAL语言的语言的子集子集z 过程可过程可嵌套定义,内层嵌套定义,内层可引用包围它的外层定义的可引用包围它的外层定义的标识符标识符, ,可递归调用可递归调用z 数据类型数据类型, ,只有整型只有整型z 数据结构

3、数据结构 , ,只有简变和常数只有简变和常数z 标识符的有效长度是标识符的有效长度是1010z 语句种类:语句种类: begin/endbegin/end、ifif、whilewhile、赋值、赋值、read/writeread/write、callcall、constconst、varvar、procedureprocedurez 过程无参,最多可过程无参,最多可嵌套嵌套三层三层z 1313个保留字:个保留字:ifif、thenthen、whilewhile、dodo、readread、writewrite、callcall、beginbegin、endend、constconst、varv

4、ar、procedureprocedure、oddoddz + +、- -、* *、/ /、= =、 、= 、=、( (、) )4 PL/0PL/0程序示例程序示例 CONST A=10; CONST A=10; (* * 常量说明部分常量说明部分 * *) VAR B,C; VAR B,C; (* * 变量变量说明部分说明部分 * *) PROCEDURE PROCEDURE P; P; (* * 过程过程说明部分说明部分 * *) VAR D;VAR D;(* * P P的局部变量的局部变量说明部分说明部分 * *) PROCEDURE PROCEDURE Q; Q; (* * P P的局

5、部过程的局部过程说明部分说明部分 * *) VAR X;VAR X; BEGINBEGIN READ(X); READ(X); D:=X; D:=X; IF X#0 DO CALL P; IF X#0 DO CALL P; END; END; BEGINBEGIN CALL Q; WRITE(D); CALL Q; WRITE(D); END; END; BEGIN CALL P; END.BEGIN CALL P; END.5递归计算 sum = 1! + 2 ! + . + n! var n, m, fact, sum; 递规计算 fact = m! procedure factorial

6、;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.6constidentnumbervaridentprocedureident分程序分程序语句语句分程序分程序程序程序分程序分程序.语法图语法图7identrea

7、dend语句语句表达式表达式:=begin语句语句语句语句)(ident,8PL/0PL/0语言的语言的EBNFEBNF表示表示z BNFBNF(BACKUS-NAUR FORMBACKUS-NAUR FORM)与与EBNFEBNF的介绍的介绍BNFBNF是根据美国的是根据美国的John W.BackusJohn W.Backus与丹麦的与丹麦的Peter NaurPeter Naur来命名的,它是从来命名的,它是从语法上描述程序设计语言的语法上描述程序设计语言的元语言元语言。采用。采用BNFBNF就可说明哪些符号序列是对就可说明哪些符号序列是对于某给定语言于某给定语言在语法上在语法上有效的程

8、序。有效的程序。z 构成构成EBNFEBNF的元素:非终结符,终结符,开始符,规则的元素:非终结符,终结符,开始符,规则z EBNFEBNF的元符号:的元符号: 用左右尖括号括起来的内容为用左右尖括号括起来的内容为非终结符非终结符=或或 读做读做定义为定义为,的的左部由左部由右部右部定义定义 | | 读做读做或或 表示右部候选内容表示右部候选内容 表示花括号内的内容表示花括号内的内容可重复可重复任意次或限定次数任意次或限定次数 表示方括号内的内容为表示方括号内的内容为任选项任选项 ( ) ( ) 表示圆括号内的内容表示圆括号内的内容优先优先9PL/0PL/0语言文法的语言文法的EBNFEBNF

9、表示表示程序-分程序.分程序-常量说明部分-CONST常量定义部分,常量定义;无符号整数-数字数字变量说明部分-VAR标识符,标识符;标识符-字母字母|数字 B-C-B -先调用,后结束B区A区B区C区BT 二、运行时数据的存储与访问-栈式存储假设A、C同层,且A中嵌套B子程序的调用、执行和返回l 过程被调用时,子程序的每次调用都需在数据栈顶为其分配独立的数据区l 子程序返回时,需做两件事情:一是代码返回(需记住RA),二是数据区的同步恢复(DL)l 子程序运行时,要存取外层数据区中的存储单元当前B数据区须记住:返回地址RA动态链DL记录调用者数据区基地址 静态链SL记录定义该过程的直接外层过

10、程数据区的基地址,以便访问外层数据12运行时数据栈运行时数据栈S S的变化的变化 var m1,m2,m3;var m1,m2,m3; Procedure A; Procedure A; var a1; var a1; procedure B; procedure B; var b1,b2; var b1,b2; procedure C; procedure C; C C过程过程call B;call B; r1r1: : B B过程过程call C; call C; r2:r2: A A过程过程call B; call B; r3:r3: 主程序主程序Call A; Call A; r4:r

11、4: B的临时单元 b2=120 b1=50 RA: r1 DL:115 SL:106 RA: r2 DL:110 SL:110 b2=25 b1=20 RA: r3 DL:106 SL:106 a1=15 RA: r4 DL:100 SL:100 m3=118 m2=472 m1=335 RA:0 DL:0 T B SL:0 100 13三、PL/0机的指令系统 f: 功能码l: 层次差 (标识符引用层减去定义层)a:根据不同的指令有所区别f l af l a指令格式:指令格式:所有运算对栈顶的两个或一个元素进行,并用运算结果代替原来的运算对象。14指指令令功功能能表表15( 0) jmp

12、0 8 转向转向主程序入口主程序入口( 1) jmp 0 2 转向转向过程过程p入口入口( 2) int 0 3 为过程为过程p开辟空间开辟空间( 3) lod 1 3( 4) lit 0 10( 5) opr 0 2( 6) sto 1 4( 7) opr 0 0 退栈并返回调用点退栈并返回调用点( 8) int 0 5( 9) opr 0 16 (10) sto 0 3(11) lod 0 3(12) lit 0 0(13) opr 0 9(14) jpc 0 24 条件不满足转条件不满足转24(15) cal 0 2 (16) lit 0 2(17) lod 0 4(18) opr 0

13、4(19) opr 0 14(20) opr 0 15 换行换行(21) opr 0 16(22) sto 0 3(23) jmp 0 11(24) opr 0 0 SL 0DL 0RA 0变量变量b变量变量cRA 16SL 0DL 0运行栈运行栈c o n s t a = 1 0 ;v a r b , c ;p r o c e d u r e p ; begin c : = b + a ; end;begin r e a d ( b ) ; while b#0 do begin c a l l p ; w r i t e ( 2 * c ) ; r e a d ( b ) ; endend.

14、SL:静态链:静态链DL:动态链:动态链RA:返回地址:返回地址0演示执行过程163 PL/0PL/0编译程序的实现编译程序的实现zPL/0PL/0编译程序的总体设计编译程序的总体设计zPL/0PL/0编译程序词法分析的设计与实现编译程序词法分析的设计与实现zPL/0PL/0编译程序语法分析的设计与实现编译程序语法分析的设计与实现zPL/0PL/0编译程序语义分析的设计与实现编译程序语义分析的设计与实现zPL/0PL/0编译程序语法错误处理的实现编译程序语法错误处理的实现zPL/0PL/0编译程序代码生成的实现编译程序代码生成的实现zpcodepcode代码解释器的设计与实现代码解释器的设计与

15、实现173.1 PL/03.1 PL/0编译程序的总体设计编译程序的总体设计z 单趟方式z 以语法、语义分析程序为核心,词法分析程序和代码生成程序都作为一个过程,当语法分析需要读单词时就调用词法分析程序,而当语法、语义分析正确,需要生成相应的目标代码时,则调用代码生成程序。z 表格管理程序实现变量,常量和过程标识符的信息的登录与查找。z 出错处理程序,对词法和语法、语义分析遇到的错误给出在源程序中出错的位置和与错误 性质有关的编号,并进行错误恢复。18PL/0PL/0编译程序编译程序PL/0PL/0编译程序编译程序类类 p pcodecode解释解释程序程序类类 pcode代码代码PL/0源程

16、序源程序输入数据输入数据输出数据输出数据PL/0编译程序的结构框架19 PL/0PL/0编译程序的结构编译程序的结构词法分析程词法分析程序序语法语义分析程序语法语义分析程序代码生成程序代码生成程序表格管理程序表格管理程序出错处理程序出错处理程序PL/0PL/0源程序源程序目标程序目标程序20编译系统总体流程图编译系统总体流程图PL/0编译程序语法、语义分析的核心213.2 PL/0编译程序词法分析的实现词法分析函数词法分析函数getsym()getsym()所识别的单词:所识别的单词:y保留字或关键字:如:保留字或关键字:如:BEGINBEGIN、 ENDEND、 IFIF、 THENTHEN

17、等等y运算符运算符: 如:如:+ +、- -、* *、/ /、:、:= =、# #、=、=等等y标识符标识符: 用户定义的变量名、常数名、过程名用户定义的变量名、常数名、过程名y常数常数: 如:如:1010、2525、100100等整数等整数y界符界符: 如:如:,、. . 、; ; 、( ( 、)等等词法分析过程词法分析过程:getsym():getsym()框图(框图(P19P19图图2.52.5)在编译程序中,单词的表示方式在编译程序中,单词的表示方式:(:(sym, id/numsym, id/num)22z enum symbol enum symbol nulnul, ,ident

18、ident, ,numbernumber, ,plusplus,varsymvarsym, ,procsymprocsym;z 当识别出标识符时先查当识别出标识符时先查保留字保留字表表z 保留字及内部表示对应表保留字及内部表示对应表: char wordnorwal; char wordnorwal; enum symble wsymnorw; enum symble wsymnorw;z 字符对应的字符对应的单词表:单词表: enum symble ssym256;enum symble ssym256; ssym+= ssym+=plusplus; ssym-=; ssym-=minusm

19、inus; ; z 词法分析通过三个词法分析通过三个全程量全程量 symbol symbol symsym; char id; int ; char id; int numnum; ;将识别出的单词信息将识别出的单词信息传递传递给给语法分析语法分析程序。程序。ysymsym:存放单词的类别:存放单词的类别 如:如:initial:= 60initial:= 60;中各单词对应的类别为:;中各单词对应的类别为: initial initial identident, := , := becomesbecomes, 60 , 60 numbernumber, ; , ; semicolonsemi

20、colonyidid:存放用户标识符:存放用户标识符, ,对对initialinitial(sym-sym-identident,id-id-initialinitial)ynumnum:存放用户定义的数:存放用户定义的数 对对6060(sym-sym-number,number,num-num-6060)23用状态转换图实现词法分析程序的设计方法用状态转换图实现词法分析程序的设计方法状态状态,对应每个状态编一段程序,对应每个状态编一段程序,每个状态每个状态调用调用取字符取字符程程序,根据当前字符序,根据当前字符转到不同的状态,并做相应操作。转到不同的状态,并做相应操作。表示表示终态终态,已,

21、已识识别出一个别出一个单词单词1 12 23 35 514141313121210109 97 78 86 64 41111空格空格字母字母字母数字字母数字非字母数字非字母数字数字数字数字数字非数字非数字:= = = =非非= =, + - ( 243.3 PL/03.3 PL/0编译程序语法分析编译程序语法分析z语法分析的设计与实现语法分析的设计与实现y 自顶向下的语法分析自顶向下的语法分析y 递归子程序法递归子程序法(递归下降分析器(递归下降分析器recursive-descent parser):对应对应每个非终结符每个非终结符(语法成分),(语法成分),编一个独立的处理子程序。编一个独

22、立的处理子程序。 由由 开始,按规则右部开始,按规则右部(语法描述图语法描述图箭头箭头方向方向)进行分析进行分析 遇到遇到非终结符非终结符,则,则调用调用相应的相应的处理过程处理过程 遇到遇到终结符终结符,则判断当前读入的单词是否与该终结符,则判断当前读入的单词是否与该终结符相匹相匹配配,若匹配,再读取下一个单词继续分析。,若匹配,再读取下一个单词继续分析。 程序程序 pl/0分程序分程序 block语句语句statement条件条件condition表达式表达式expression 项项term因子因子 factor语语法法调调用用关关系系图图26VAR A;VAR A;BEGINBEGIN

23、 READ(A) READ(A)END.END. . . VARVAR ; A A BEGINBEGIN ENDEND READREAD ( ) A A 为文法的为文法的开始符号开始符号,以开,以开始符号作为根结始符号作为根结点存在一棵倒挂点存在一棵倒挂着的语法树。着的语法树。递归下降语法分递归下降语法分析过程隐含着对析过程隐含着对对语法树的前序对语法树的前序遍历遍历27表达式表达式=+|-+|-项项 (+|-+|-)项)项 int expression(bool* fsys, int* ptx, int lev)if(sym=plus | sym=minus) getsymdo; termd

24、o(nxtlev, ptx, lev); /处理项 elsetermdo(nxtlev, ptx, lev); / 处理项 while (sym=plus | sym=minus)getsymdo; termdo(nxtlev, ptx, lev); / 处理项 return 0;注意一致性:进入每一语法单位处理程序之前,其第一个单词已读出,退出时,应读出下一个语法单位的第一个单词28项项=因子因子 (* *|/|/)因子)因子 int term(bool* fsys, int* ptx, int lev)factordo(nxtlev, ptx, lev); /* 处理因子 */ while

25、(sym=times | sym=slash)getsymdo; factordo(nxtlev, ptx, lev);return 0;29因子因子=标识符标识符| |无符号整数无符号整数|(表达式表达式)int factor(bool* fsys, int* ptx, int lev)if(sym = ident)/* 因子为常量或变量 */ getsymdo; else if(sym = number) getsymdo; else if (sym = lparen)/* 因子为表达式 */ getsymdo; expressiondo(nxtlev, ptx, lev); if (sy

26、m = rparen) getsymdo; else error(22);/* 缺少右括号 */ return 0;303.4 PL/03.4 PL/0语义分析的设计与实现语义分析的设计与实现z 说明部分的分析说明部分的分析与处理与处理z 表格管理表格管理z 过程体过程体( (语句)的分析语句)的分析与处理与处理31说明部分的分析说明部分的分析与处理与处理-登录符号表登录符号表z 对每个过程(含主程序)对每个过程(含主程序)说明的对象说明的对象(变量变量,常量常量和和过程过程)造符号表造符号表z 登录登录标识符的标识符的属性属性。z 标识符的属性标识符的属性: :种类,所在种类,所在层次层次,

27、 ,值值和分配的和分配的相对位置相对位置。z 登录信息由登录信息由ENTERENTER过程完成。过程完成。符号表结构enum object constant, variable, procedur;struct tablestruct char nameal; enum object kind; int val, level, adr, size; tabletxmax; 32const a=35;/const a=35;/常量无层次常量无层次var a1,a2,a3;var a1,a2,a3;Procedure P;Procedure P; var b1,b2; var b1,b2; pro

28、cedure P1; procedure P1; var c; var c; procedure P2; procedure P2; var d; var d; 注意:在单趟编译中,对于并列的函数(或分程序),其相注意:在单趟编译中,对于并列的函数(或分程序),其相应的符号表不会同时存在。应的符号表不会同时存在。过程过程P2在在code的的入口入口 (0) jmp 0 0 CX (1) jmp 0 0 (2) jmp 0 0 (k) jmp 0 0 名字名字 类类 值值 层次层次 地址地址 大小大小33: :=varvar, ;if(sym=varsym)/if(sym=varsym)/* *

29、 收到变量声明符号,开始处理变量声明收到变量声明符号,开始处理变量声明 * */ / getsymdo; getsymdo; dovardeclarationdo(&tx, lev, &dx); dovardeclarationdo(&tx, lev, &dx); while (sym = comma) while (sym = comma) getsymdo; getsymdo; vardeclarationdo(&tx, lev, &dx); vardeclarationdo(&tx, lev, &dx); if (sym =

30、 semicolon) if (sym = semicolon) getsymdo;getsymdo; else error(5);else error(5); while (sym = ident); while (sym = ident); 注意:注意:&tx&tx34变量说明处理变量说明处理int vardeclaration(intint vardeclaration(int* * ptx,int lev,int ptx,int lev,int* * pdx) pdx)if (sym = ident)if (sym = ident) enter(variable, pt

31、x, lev, pdx);/enter(variable, ptx, lev, pdx);/填写名字表填写名字表 getsymdo; getsymdo; else else error(4); error(4); / /* * var var后应是标识后应是标识符符 * */ / return 0; return 0; 35过程过程ENTERENTER的实现的实现/ /* * 在名字表中加入一项在名字表中加入一项 * * * * k: k: 名字种类名字种类const,var or procedureconst,var or procedure * * ptx: ptx: 名字表尾指针名字表尾

32、指针 * * lev: lev: 名字所在的层次名字所在的层次, ,以后所有的以后所有的levlev都是这样都是这样 * * pdx: pdx: 当前应分配变量的相对地址,分配后增加当前应分配变量的相对地址,分配后增加1 1 * */ /void enter(enum object k, intvoid enter(enum object k, int* * ptx,int lev, int ptx,int lev, int* * pdx) pdx)(* *ptx)+;ptx)+; strcpy(table( strcpy(table(* *ptx).name, id); ptx).name,

33、 id); / /* * 全局变量全局变量idid中已存有当前名字的名字中已存有当前名字的名字 * */ / table( table(* *ptx).kind = k;ptx).kind = k;36 switch (k)switch (k) case constant:case constant: / /* * 常量名字常量名字 * */ / if (num amax) if (num amax) error(31); error(31);/ /* * 数越界数越界 * */ / num = 0; num = 0; table( table(* *ptx).val = num;ptx).v

34、al = num; break; break; case variable:case variable: / /* * 变量名字变量名字 * */ / table( table(* *ptx).level = lev;ptx).level = lev; table( table(* *ptx).adr = (ptx).adr = (* *pdx);pdx); ( (* *pdx)+;pdx)+; break; break; case procedur: case procedur: / /* *过程名字过程名字* */ / table( table(* *ptx).level = lev;pt

35、x).level = lev; break; break; 37过程体的处理变量引用的处理过程体的处理变量引用的处理y对对语句进行语句进行语法语法分析分析y语义分析语义分析 当遇到当遇到标识符的引用时标识符的引用时就调用就调用POSITIONPOSITION函数函数查查TABLETABLE表表,看是否,看是否有有过过正确定义正确定义,若已有,则从表中,若已有,则从表中取相应取相应的有关的有关信息信息,供代码的生成使用。,供代码的生成使用。若无定义则错若无定义则错。y语义分析语义分析 TABLETABLE表表若已若已有有过过正确定义正确定义,检查引用与说明的,检查引用与说明的属性是否一致,属性是

36、否一致,若不一致则错若不一致则错。y当当语法语义正确时语法语义正确时,就,就生成生成相应语句功能的相应语句功能的目标代码目标代码intint position( position(charchar* * id) id) intint i; i; strcpy(, id);strcpy(, id); i = tx + 1;i = tx + 1; whilewhile(strcmp(, id) != 0);(strcmp(, id) != 0); returnreturn i; i; / position/

37、 position思考:在造表和查表过程中,如何保证每个过程的局部量不被它的外层引用?38赋值赋值语句的处理语句的处理if (sym = ident) if (sym = ident) / /* * 准备按照赋值语句处理准备按照赋值语句处理 * */ / i = position(id, i = position(id, * *ptx);ptx); if (i = 0) error(11); if (i = 0) error(11);/ /* * 变量未找到变量未找到 * */ / elseif(tablei.kind != variable) elseif(tablei.kind != va

38、riable) error(12);error(12); / /* * 赋值语句格式错误赋值语句格式错误 * */ / i = 0; i = 0; else.else. gendo(sto,lev-tablei.level,tablei.adr); gendo(sto,lev-tablei.level,tablei.adr); . . 39因子因子=标识符标识符| |无符号整数无符号整数|(表达式表达式)int factor(bool* fsys, int* ptx, int lev) /因子的语义分析if(sym = ident)/* 因子为常量或变量 */i = position(id,

39、*ptx);/* 查找名字 */ if (i = 0) error(11); /* 标识符未声明 */ else switch (tablei.kind) case constant:/* 名字为常量 */ break; case variable: /* 名字为变量 */ break; case procedur:/* 名字为过程 */ error(21); /* 不能为过程名 */403.5 编译程序的错误处理错误处理的原则:尽可能准确指出出错位置,错误性质,错误处理的原则:尽可能准确指出出错位置,错误性质,尽可能进行校正。尽可能进行校正。PL/0PL/0编译程序对语法错误的处理:编译程序

40、对语法错误的处理:(1)(1)对于对于易于校正易于校正的错误,如丢了逗号,分号等,指出出的错误,如丢了逗号,分号等,指出出错位置,错位置,加以校正加以校正,继续进行分析。,继续进行分析。(2)(2)对于对于难于校正难于校正的错误,给出错误的位置与性质,的错误,给出错误的位置与性质,跳过跳过后面的一些单词后面的一些单词,直到下一个可以进行正常语法分析的直到下一个可以进行正常语法分析的语法单位语法单位41 z 在在进入进入某个某个语法单位语法单位时,时,调用调用TESTTEST, ,检查当前符号检查当前符号是否属于该是否属于该语法单位的开语法单位的开始符号集合始符号集合。若不属于,。若不属于,则则

41、滤去滤去开始开始符号符号和和后跟后跟符符号号集合外集合外的所有符号。的所有符号。z 在在语法单位语法单位分析结束分析结束时,时,调用调用TESTTEST, ,检查当前符号检查当前符号是否属于调用该语法单位是否属于调用该语法单位时应有的时应有的后跟后跟符号集合。符号集合。若不属于,则若不属于,则滤去滤去后跟后跟符符号和号和开始开始符号符号集合外集合外的所的所有符号。有符号。 TEST TEST TEST TEST42z 开始符号集合 bool declbegsyssymnum,statbegsyssymnum,facbegsyssymnum; declbegsys: constsym,varsy

42、m,procsym; statbegsys: beginsym,callsym,ifsym,whilesym,readsym,writesym; facbegsys: ident,number,lparen;z 后跟符号集合fsys作为参数: int test(bool* s1, bool* s2, int n); int block(int lev, int tx, bool *fsys); int statement(bool* fsys, int * ptx, int lev); int expression (bool* fsys, int * ptx, int lev); int t

43、erm (bool* fsys, int * ptx, int lev); int factor (bool* fsys, int * ptx, int lev);为symble的元素数32后跟符号集TESTSYM在在S1中中?打印出错编号打印出错编号nS1:=S1+S2SYM在在S1中中?GETSYM返回返回YYNNTEST测试过程流程图测试过程流程图44因子的处理过程因子的处理过程procedure factor(fsys:symset); var i:integer; begin 入口: test(facbegsys,fsys,24); while sym in facbegsys do

44、 begin if . 出口: test(fsys,facbegsys,23); end end;Facbegsysy 处理处理ident number lparentestntest45后跟符集是逐步补充的,需补充的内容与当前所处小环境有关。对调用expression(fsys); z 由于write语句的语法write(,); 所以在write语句中调用expression时后跟符为: expression(rparen,comma+fsys);zfactor的语法:factor=.|( exp ) 在factor中调用expression时后跟符 expression(rparen+fs

45、ys);463.6 代码生成代码生成是由过程代码生成是由过程GENGEN完成。完成。GENGEN有有3 3个个参数参数,分别代表目标代码的,分别代表目标代码的功能码功能码,层差层差和和位移量位移量。例如。例如 gen(opr,0,16); gen(opr,0,16); gen(sto, gen(sto,levlev- -levellevel,adr),adr) levlev:当前:当前处理的处理的过程过程层次层次 levellevel:被引用变量或过程所在:被引用变量或过程所在层次层次 CXCX:为目标代码:为目标代码codecode数组的下标指针数组的下标指针47代码结构变换, 地址回填ge

46、tsym;condition;if sym=thensym then getsym else error(16);cx1:= cx;gen(jpc,0,0)statement( );codecx1.a:=cxIf c then s48int main() . if(-1=block(0, 0, nxtlev) . . interpret(); / 调用解释执行程序 .int block(int lev, int tx, bool* fsys) dx=3; tx0=tx; tabletx.adr=cx; gen(jmp,0,0); /生成转向过程体入口的指令 while (sym = procs

47、ym) getsymdo(); if(sym=ident) enter(procedur, &tx, lev, &dx); . if (-1 = block(lev+1, tx, nxtlev) . .3.7 PL/0分程序的处理子程序分程序的处理子程序-block初值为fsysperiod+declbegsys+statbegsys49下标指针下标指针cx,tx和变量和变量dx的作用的作用CX:为目标代码code数组的下标指针。实际上目标代码的顺序是内层过程的在前边,主程序的目标代码在最后。tx :table表的下标指针,是以值参数形式使用的。dx: 计算每个变量在运行栈中相

48、对本过程基地址的偏移量 ,放在table表中的adr域,生成目标代码时再放在code中的a域。过程体入口时的处理codetabletx0.adr.a=cx; /过程入口地址填写在code中tabletx0.adr=cx; /过程的入口填写在table中tabletx0.size=dx; /过程占的空间填写在table中 cx0=cx; /保留过程在code中的入口地址gen(int,0,dx); /生成过程入口指令503.8 类pcode解释器z目标代码存放在数组CODE中(程序地址寄存器p)z解释程序定义一个一维整型数组S作为运行栈z栈顶寄存器(指针)t,基址寄存器(指针)b,指令寄存器i(

49、当前正在解释的目标指令)51目标代码的解释执行目标代码的解释执行几条几条特殊指令特殊指令在在code中的中的位置位置和和功能功能yINT 0 AINT 0 A在在过程过程目标程序的目标程序的入口处入口处,开辟开辟A A个单元的数据段。个单元的数据段。A A为为局局部变量部变量的的个数个数+ +3 3。yOPR 0 0OPR 0 0在在过程过程目标程序的目标程序的出口处出口处,释放数据段释放数据段(退栈),(退栈),恢复调恢复调用用该过程该过程前前正在运行的过程正在运行的过程的数据段的数据段基址寄存器基址寄存器B B和和栈顶栈顶寄存器寄存器T T的值,并将的值,并将返回地址返回地址送送到指令地址

50、寄存器到指令地址寄存器P P中。中。yCAL L ACAL L A调用过程调用过程,填写填写静态链静态链、动态链动态链、返回地址返回地址,给出,给出被调被调用用过程过程的的基地址基地址值,值,送送入基址寄存器入基址寄存器B B中,目标程序的中,目标程序的入口入口地址地址A A的值的值送送指令地址寄存器指令地址寄存器P P中,使指令从中,使指令从A A开始执行开始执行interpret三个寄存器赋初值三个寄存器赋初值t:=0; b:=1; p:=0;主程序的主程序的SL,DL,RA赋初值赋初值s1:=0; s2=0; s3=0;i:=codep;p:=p+1;P=0?返回返回解释执行的流程图解释执行的流程图执行指令执行指令iNY53几条特殊指令的解释执行过程过程出口出口opr 0 0opr 0 0 RA RA DL DL SL SLb. tMtbt=b-1;p=st+3;b=st+2Q54调用过程调用过程-cal l acal l a st+1=base(l, s, b); 填写静态链 st+2=b; 填写动态链 st+3=p; 填写返回地址 b=t+1; 被调用过程的基地址 p=a 过程入口地址a送p /t在int中设置int

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论