PLO语言功能扩展case语句和for语句Word文档下载推荐.docx

上传人:b****1 文档编号:1033840 上传时间:2023-04-30 格式:DOCX 页数:23 大小:112.32KB
下载 相关 举报
PLO语言功能扩展case语句和for语句Word文档下载推荐.docx_第1页
第1页 / 共23页
PLO语言功能扩展case语句和for语句Word文档下载推荐.docx_第2页
第2页 / 共23页
PLO语言功能扩展case语句和for语句Word文档下载推荐.docx_第3页
第3页 / 共23页
PLO语言功能扩展case语句和for语句Word文档下载推荐.docx_第4页
第4页 / 共23页
PLO语言功能扩展case语句和for语句Word文档下载推荐.docx_第5页
第5页 / 共23页
PLO语言功能扩展case语句和for语句Word文档下载推荐.docx_第6页
第6页 / 共23页
PLO语言功能扩展case语句和for语句Word文档下载推荐.docx_第7页
第7页 / 共23页
PLO语言功能扩展case语句和for语句Word文档下载推荐.docx_第8页
第8页 / 共23页
PLO语言功能扩展case语句和for语句Word文档下载推荐.docx_第9页
第9页 / 共23页
PLO语言功能扩展case语句和for语句Word文档下载推荐.docx_第10页
第10页 / 共23页
PLO语言功能扩展case语句和for语句Word文档下载推荐.docx_第11页
第11页 / 共23页
PLO语言功能扩展case语句和for语句Word文档下载推荐.docx_第12页
第12页 / 共23页
PLO语言功能扩展case语句和for语句Word文档下载推荐.docx_第13页
第13页 / 共23页
PLO语言功能扩展case语句和for语句Word文档下载推荐.docx_第14页
第14页 / 共23页
PLO语言功能扩展case语句和for语句Word文档下载推荐.docx_第15页
第15页 / 共23页
PLO语言功能扩展case语句和for语句Word文档下载推荐.docx_第16页
第16页 / 共23页
PLO语言功能扩展case语句和for语句Word文档下载推荐.docx_第17页
第17页 / 共23页
PLO语言功能扩展case语句和for语句Word文档下载推荐.docx_第18页
第18页 / 共23页
PLO语言功能扩展case语句和for语句Word文档下载推荐.docx_第19页
第19页 / 共23页
PLO语言功能扩展case语句和for语句Word文档下载推荐.docx_第20页
第20页 / 共23页
亲,该文档总共23页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

PLO语言功能扩展case语句和for语句Word文档下载推荐.docx

《PLO语言功能扩展case语句和for语句Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《PLO语言功能扩展case语句和for语句Word文档下载推荐.docx(23页珍藏版)》请在冰点文库上搜索。

PLO语言功能扩展case语句和for语句Word文档下载推荐.docx

类pcode代码

实现工具(平台):

2.结构设计说明:

PlO所有子程序如下:

过程或函数名

简要功能说明

main

初始化编译环境,建立关键字表,调用分程序Block对源文件进行编译,当编译正确时,自动调用解释执行程序,对目标代码进行解释执行。

error

出错处理,打印出错位置和错误性质编号。

并在信息栏输出错误信息。

getch

过滤空格,读取一个字符

getsym

词法分析,读取一个单词

gen

生成目标代码(类pcode代码),并送入目标程序区。

test

测试当前单词是否是合法

block

分程序分析处理过程。

enter

登录过程说明对象包括变量、常量和过程名的属性信息到符号表。

position

查找标识符在符号表中的位置。

constdeclaration

常量定义处理,收集常量信息并登录到符号表。

vardeclaration

变量定义处理,收集变量信息并登录到符号表。

listcode

列出目标代码清单。

statement

语法分析,语句部分处理。

expression

表达式分析处理。

term

项分析处理过程。

factor

因子分析处理。

condition

条件处理。

interpret

对目标代码进行解析执行。

Base

通过静态链求数据区首地址。

3.增加for语句:

(1)设计思想:

For语句的语法分析:

设计思路:

主要分为两部分模块:

一,for和;

之间的赋值语句处理;

二,条件语句处理和最后的语句处理。

首先获取赋值号左边的标识符,从符号表中找到它的信息,并确认这个标识符确为变量名。

然后通过调用表达式处理过程算得赋值号右部的表达式的值并生成相应的指令保证这个值放在运行期的数据栈顶。

最后通过前面查到的左部变量的位置信息,生成相应的STO指令,把栈顶值存入指定的变量的空间,实现了赋值操作。

返回函数值也是用赋值语句进行返回值的储存。

首先调用condition函数处理条件语句,并且把当前condition处理生成的判断条件操作代码的的地址cx保存到cx1。

每个循环体中,在循环体结束前,设置跳回判断操作判断当前条件是否跳出循环。

都把本循环体结束的下一个位置保存到cx2生成跳转,并在循环结束时用cx2更新为目前循环结束跳转地址。

难点分析:

本模块,主要难点是处理循环体的跳转,解决方法参照上点。

不过可以参照if语句和while语句。

(2)扩充代码:

1)在头文件pl0.h中的符号symbol中增加所要求增加的符号,用加粗倾斜红色字体标出:

2)源代码:

if(sym==forsym)/*准备按照for语句处理*/

{

getsymdo;

if(sym==ident)/*按照赋值语句处理*/

{

i=postion(id,*ptx);

if(i==0)error(11);

/*变量未找到*/

else

{

if(table[i].kind!

=variable)

{

error(12);

/*for语句格式错误或者赋值语句格式错误*/

i=0;

}

}

getsymdo;

if(sym==becomes)

getsymdo;

}

elseerror(13);

/*检测赋值符号*/

memcpy(nxtlev,fsys,sizeof(bool)*symnum);

expressiondo(nxtlev,ptx,lev);

/*处理赋值符号右侧表达式*/

if(i!

=0)

{

gendo(sto,lev-table[i].level,table[i].adr);

/*expression将执行一系列指令,但最终结果将会保存在栈顶,执行sto命令完成赋值*/

}

}

elseerror(17);

cx1=cx;

/*保存判断条件操作的位置*/

getsymdo;

memcpy(nxtlev,fsys,sizeof(bool)*symnum);

nxtlev[dosym]=true;

/*后跟符号为do*/

conditiondo(nxtlev,ptx,lev);

/*调用条件处理*/

cx2=cx;

/*保存循环体的结束的下一个位置*/

gendo(jpc,0,0);

/*生成条件跳转,但跳出循环的地址未知*/

if(sym==dosym)

getsymdo;

elseerror(18);

/*缺少do*/

statementdo(fsys,ptx,lev);

/*循环体*/

gendo(jmp,0,cx1);

/*回头重新判断条件*/

code[cx2].a=cx;

/*反填跳出循环的地址,与if类似*/

}

4.增加case语句:

Case语句的语法分析:

}endcase

按照上述语法分析图,先写出格式判断,建立语句处理的框架。

再细致写出伪代码的生成核心部分。

(以下分析中提及的“循环体”是指上面语法分析图的循环结构)

依照语法要求写出语法分析的框架,大致如上分析图。

首先,将变量的位置存到blpst,供后面生成变量与常量比较指令用。

用casenum记下case含有的情况个数。

每个循环体开始,取得常量之后,生成三条指令lod(将变量压到栈顶)、lit(将常量押到栈顶)、opr08(两者作比较)。

在生成后面语句的代码之前,生成jpc利用变量和常量比较所得结果进行跳转,若为假,则跳到本循环体结束的地方。

接着,对循环体内语句进行处理。

生成无条件跳转指令跳转到case语句结束,由于地址未知,要等先把各个循环体中的无条件跳转指令的地址放到cxjmpadr数组中,待case结束后再回填跳转地址。

最后,回填本循环体头的条件跳转地址。

难点分析:

1.处理常量与变量的比较。

一开始以为应该跟if语句类似,处理常量与变量的比较的时候发现这一点跟if语句压根不同,而且要难得多。

不过,后来认识到变量的本质,从生成的汇编代码的角度出发,利用生成三条指令lod(将变量压到栈顶)、lit(将常量押到栈顶)、opr08(两者作比较)解决了这个问题。

2.循环体的跳转问题,比较复杂。

简单来说,三点跳转的关键点:

一,循环体头的判断跳转;

二,循环倒数第二个操作,跳出case语句操作;

三,最后的回填条件跳转操作。

2)源代码:

if(sym==casesym)/*case语句*/

if(sym!

=ident)

error(14);

/*case后应为标识符*/

else

intblpst=i=postion(id,*ptx);

/*将变量的position保存在blpst中*/

if(i==0)

error(11);

/*标识符未找到*/

else

if(table[i].kind!

error(38);

/*case后的标识符应该为变量*/

if(sym!

=colon)

error(39);

/*应该为冒号*/

intcasenum=0;

/*casenum记录情况个数*/

intcxjmpadr[50];

/*cxjmpadr用于存储各种情况中转移指令的地址*/

intcxb=cx;

/*cxb存储case语句开始的指令地址*/

intcjpc;

/*当前情况处理完常量标号后的跳转指令地址*/

intvarpst=i;

/*存放case后面变量的position*/

intconpst;

/*存放当前处理情况的常量标号的position*/

intjjj;

for(jjj=0;

jjj<

50;

jjj++)

{

cxjmpadr[jjj]=0;

do

getsymdo;

if(sym!

=ident)/*是否为标识符*/

error(37);

/*case语句体中,冒号前面应该为标识符*/

else

conpst=i=postion(id,*ptx);

if(i==0)

{

error(11);

}

else

if(table[i].kind!

=constant)

{

error(40);

/*标识符应该为常量*/

}

getsymdo;

if(sym!

error(39);

memcpy(nxtlev,fsys,sizeof(bool)*symnum);

nxtlev[semicolon]=true;

nxtlev[colon]=true;

nxtlev[endcasesym]=true;

/*后跟符号为分号或end*/

gendo(lod,lev-table[blpst].level,table[blpst].adr);

/*将case后变量放到栈顶*/

gendo(lit,lev-table[conpst].level,table[conpst].val);

/*将当前常量放到栈顶*/

gendo(opr,0,8);

/*将当前栈顶和次栈顶比较,看是否相等,是为真,否为假放到次栈顶*/

cjpc=cx;

/*记住跳转语句代码地址*/

gendo(jpc,0,0);

/*设置条件跳转,地址暂时未知*/

statementdo(nxtlev,ptx,lev);

cxjmpadr[casenum++]=cx;

/*记住当前情况的jmp语句代码地址*/

gendo(jmp,0,0);

/*设置跳出case语句,跳转地址暂时未知*/

code[cjpc].a=cx;

/*回填jpc跳转地址*/

printf("

%d\n"

code[cjpc].a);

}while(sym==semicolon);

if(sym!

=endcasesym)

error(36);

/*结束符号因该为endcase*/

/*回填各个情况处理中的jmp语句的跳转地址*/

casenum;

code[cxjmpadr[jjj]].a=cx;

5.相关代码的修改

说明:

修改部分为红色加粗字体

1).h中文件的修改:

/*关键字个数*/

#definenorw17

/*符号*/

enumsymbol{nul,ident,number,plus,minus,times,slash,oddsym,eql,neq,lss,leq,

gtr,geq,lparen,rparen,comma,semicolon,colon,period,becomes,beginsym,

endsym,ifsym,thensym,whilesym,writesym,readsym,dosym,callsym,

constsym,varsym,procsym,forsym,casesym,endcasesym};

#definesymnum36

2)初始化函数init()中的修改:

/*设置保留字名字*/

strcpy(&

(word[0][0]),"

begin"

);

(word[1][0]),"

call"

(word[2][0]),"

case"

(word[3][0]),"

const"

(word[4][0]),"

do"

(word[5][0]),"

end"

(word[6][0]),"

endcase"

(word[7][0]),"

for"

(word[8][0]),"

if"

(word[9][0]),"

odd"

(word[10][0]),"

procedure"

(word[11][0]),"

read"

(word[12][0]),"

then"

(word[13][0]),"

var"

(word[14][0]),"

while"

(word[15][0]),"

write"

/*设置保留字符号*/

wsym[0]=beginsym;

wsym[1]=callsym;

wsym[2]=casesym;

wsym[3]=constsym;

wsym[4]=dosym;

wsym[5]=endsym;

wsym[6]=endcasesym;

wsym[7]=forsym;

wsym[8]=ifsym;

wsym[9]=oddsym;

wsym[10]=procsym;

wsym[11]=readsym;

wsym[12]=thensym;

wsym[13]=varsym;

wsym[14]=whilesym;

wsym[15]=writesym;

3)新增错误编号及含义:

33read语句缺少右括号

34read语句缺少左括号

35read()中的标识符应为声明过的变量

36case中丢了endcase

37case语句体开头应为标识符

38case后的标识符应为变量

39case变量后应为冒号

40case语句体开头因为常量

5.测试数据及结果:

测试用例一

1.测试代码:

文件名:

success.txt

代码:

consta=1,c=2,d=3;

varb,i,k;

begin

read(k);

b:

=0;

fori:

i<

=kdo

begin

=b+i;

i:

=i+1;

end;

write(b);

read(i);

casei:

a:

=11;

c:

=22;

d:

=33

endcase;

write(b)

end.

2.测试说明:

首先输入源文件文件全名success.txt。

在输入一个整数x,函数将输出x从0到x的所有整数和。

接着,输入1或者2或者3,将相应输出11、22、33。

本测试用例中既含有for语句,有含有case语句,同时测试了两种语句的功能。

3.运行截图:

测试用例二

error.txt

consta=10,c=1,d=2;

k

=i+1

write(b;

=1;

casea:

=a;

=c+a;

=a

下输入文件全名error.txt。

程序语法有错,运行后会有报错信息,但是还是会生成汇编代码。

报错编号与课本一样,不过新增36到40几个编号。

其他测试用例说明:

以下说明的程序文件在工程文件夹里。

程序ab.txt:

简单的输入输出测试;

程序adder.txt、adder2.txt:

累加的for语句测试程序;

程序casess.txt:

case测试语句。

6.实验感想:

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 求职职场 > 简历

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2