PL0课程设计 多种思路.docx
《PL0课程设计 多种思路.docx》由会员分享,可在线阅读,更多相关《PL0课程设计 多种思路.docx(37页珍藏版)》请在三一办公上搜索。
1、PL0课程设计 多种思路语句 Ident := += -= + - 表达式 + Ident - If 条件 Then 语句 Else 语句 因子 To For 语句 Downto 表达式 To 语句 Number Ident 表达式 )+ - 1. 增加一维数组类型 l 增加一维数组后的声明语句语法描述图: l EBNF语法描述::=var, l 识别数组部分代码实现,在getsym和enter里改动 if(ch=)/如果是则认为是数组 getchdo; getsymdo; sum=num;/把getsym取出的数字赋给sum,作为数组的维数 if(ch=)/维数后的应该是 getchdo;
2、sym=arrayp; else error(33);/如果没有报错 if(sum1) error(34);/数组维数不能为0 /-把一维数组当作变量,把数组填入名字表table里,在enter- switch(k) case array: /数组时 table(*ptx)-1.size=sum;/为数组变量开辟一个长度sum的空间 for(i=0;isum) i=i+sum+1;/使用单元为数组首单元+该单元编号+1 else error(35); sum=0; return i; 详细版 添加一维数组需要对PL0进行如下修改: 添加一维数组变量类型的声明的处理以及识别; 处理一维数组作为变
3、量时在表达式及语句中的变量引用情况; 处理一维数组进行+和运算; 处理一维数组在运行栈里的存取问题; 检测一维数组下标界合法性问题。 完成数组的添加的主导思想为,把数组元素转化为变量处理,从而充分利用之前为变量设定的各种操作。 (1) 添加一维数组变量类型的声明的处理以及识别 首先在枚举类型kind中添加array及null。 修改后kind为: enum object constant, variable, procedur, array, null, ; 同时结构体类型中tablestruct中的size除了表示procedure的大小外,同时用于表示数组的大小。 添加数组左右中括号的sy
4、mbol,左中括号lepa,右中括号ripa,同时修改symnum 变为43(41+2),以及init函数中进行如下修改 ssym+=plus; ssym-=minus; ssym*=times; ssym/=slash; ssym(=lparen; ssym)=rparen; ssym=eql; ssym,=comma; ssym.=period; /ssym#=neq; ssym;=semicolon; ssym=lepa;/数组用新增 ssym=repa;/数组用新增 添加int类型全局变量arraysize。用于暂时存储数组大小。 在变量声明处理过程vardeclaration中添加对
5、一维数组的声明处理。若变量后接左中括号则为数组。修改如下: int vardeclaration(int * ptx,int lev,int * pdx) int i; char idtempal+1;/临时保存数组名字 if(sym=ident) strcpy(idtemp,id); getsymdo; /如果是数组 if(sym=lepa)/数组的左中括号 getsymdo; if(sym=number)/a中的中括号里是数字的话 *pdx=*pdx+num;/为数组分配空间 arraysize=num;/保存数组的长度 else if(sym=ident)/a中的中括号里是变量的话 /要
6、检查是不是以声明的常量 i=position(id,*ptx);/查找名字表 if(i=0) error(11);/标识符未说明 else if(tablei.kind=constant)/标识符的属性是常量 *pdx=*pdx+tablei.val;/为数组分配空间 arraysize=tablei.val;/保存数组的长度 else error(25);/数组下标定义不符合规定,应为常量 /if else error(25);/数组下标定义不符合规定,应为常量 /else strcpy(id,idtemp);/恢复数组名字id enter(array,ptx,lev,pdx);/填写名字表
7、 getsymdo; if(sym!=ripa)/如果不是结尾 error(26); else getsymdo; /if /下个字符是逗号或者分号,则不是数组,是变量 else if(sym=comma|sym=semicolon) enter(variable,ptx,lev,pdx);/填写名字表 /getsymdo; else error(4); return 0; 同时修改enter函数,增加对数组的支持 void enter (enum object k,int *ptx,int lev, int *pdx) (*ptx)+; strcpy(table(*ptx).name,id)
8、; /*全局变量id中已存有当前名字的名字*/ table(*ptx).kind=k; switch(k) case constant: /*常量名字*/ if (numamax) error(31); num=0; table(*ptx).val=num; break; case variable: /*变量名字*/ table(*ptx).level=lev; table(*ptx).adr=(*pdx); table(*ptx).size=0; (*pdx)+; break; /*过程名字*/ case procedur: table(*ptx).level=lev; break; ca
9、se array: /*数组名字*/ table(*ptx).level=lev; table(*ptx).adr=(*pdx)-arraysize; table(*ptx).size=arraysize; break; (2)处理一维数组作为变量时在表达式及语句中的变量引用情况,以及完成对数组越界的处理 在修改statement与factor函数前,需对虚拟机的中间代码添加对数组相关操作的支持。 修改FCT枚举类型如下 enum fct lit, opr, lod, sto, cal, inte, jmp, jpc, tra,jud,wta,rda, ; 在interup解释函数中添加对上述
10、新增功能的解释.代码如下: case tra:/将数组的下标范围入栈 st=i.a; t+; break; case rda:/读数组数据 tmd=base(i.l,s,b); st=stmd+i.a+st-1; t+; break; case wta:/写数组数据 tmd=base(i.l,s,b); stmd+i.a+st-2=st-1; t-; break; case jud:/判断数组下标的合法性 t-; if(st-1=st) error(41);/定义数组下标溢出错误 printf(数组下标溢出错误); break; 接下来可以修改stament语句,如下: int stateme
11、nt(bool* fsys,int * ptx,int lev) int i,cx1,cx2; bool nxtlevsymnum; enum symbol addop;/用于存储运算类型,新增 object type=null; if(sym=ident) i=position(id,*ptx); if(i=0) error(11); else /数组元素或变量 if(tablei.kind!=variable&tablei.kind!=array) error(12); i=0; else getsymdo; if(sym=lepa)/如果是数组 getsymdo; /处理里的表达式 me
12、mcpy(nxtlev,fsys,sizeof(bool)* symnum); nxtlevripa=true;/表达式后接符号为右中括号 expressiondo(nxtlev,ptx,lev); gendo(tra,0,tablei.size);/生成将数组下标范围入栈指令 gendo(jud,0,0);/作用判断下标合法性,完成了数组越界的处理 if(sym!=ripa) error(26);/接下来的单词不为右中括号 getsymdo; /if(sym=lepa) if(sym=becomes)/省略未改动部分 else /省略+=,-=等语句判别的代码,同时在各代码中取消存储到变量的
13、语句用下面的IF语句统一代替 if(type=array) gendo(wta,lev-tablei.level,tablei.adr); /*把数组元素的值压入栈*/ else gendo(sto,lev-tablei.level,tablei.adr); /*把变量的值压入栈*/ 在因子处理程序中,添加对一维数组的支持,在判断第一个单词为ident后的switch语句中,添加如下代码 case array: getsymdo; if(sym=lepa) memcpy(nxtlev,fsys,sizeof(bool)* symnum); nxtlevripa=true; getsymdo;
14、expressiondo(nxtlev,ptx,lev); gendo(tra,0,tablei.size);/生成将数组下标范围入栈指令 gendo(jud,0,0);/判断下标合法性 gendo(rda,lev-tablei.level,tablei.adr); /*把数组元素的值压入栈*/ if(sym!=ripa)error(42);/定义中括号不匹配错误 elsegetsymdo; break; 同时把所有读取变量存取变量的代码替换为如下代码 读变量的替换代码 if(type=array) gendo(rda,lev-tablei.level,tablei.adr); /*把数组元素
15、的值压入栈*/ else gendo(lod,lev-tablei.level,tablei.adr);/*把变量的值压入栈*/ 写变量的替换代码 if(type=array) gendo(wta,lev-tablei.level,tablei.adr); /*把数组元素的值压入栈*/ else gendo(sto,lev-tablei.level,tablei.adr); /*把变量的值压入栈*/ 上述代码中type为object类型变量。在判断变量是否为array时对其赋值。 扩充一维数组类型功能 扩充一维数组类型功能需要:一维数组变量类型的声明;一维数组的识别分析;一维数组 作为变量时在
16、表达式中的变量引用情况;一维数组可以进行+和运算;一维数组在运行 栈里的存取问题;一维数组下标界合法性问题。 一维数组的文法如下: := := | 扩充的语法描述见结构设计中的 PL/0 分程序和主要语句的语法描述中的描述图。 在标识符的属性类型里增加了 array 数组类型,详细见报告上面的说明。 在虚拟机代码指令操作码中增加了六条指令: gar,/根据栈顶的偏移地址从数组中取值到新的栈顶 sar,/根据次栈顶的偏移地址把栈顶的值存入数组 shd,/将栈顶的值下移到次栈顶,栈顶出栈,即次栈顶成为栈顶 del,/出栈顶 jud,/判断数组下标合法性 tra,/将数组的下标范围入栈,gendo(
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- PL0课程设计 多种思路 PL0 课程设计 多种 思路
链接地址:https://www.31ppt.com/p-3163881.html