

免费预览已结束,剩余14页可下载查看
下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
课 程 设 计 课程名称_编译原理_ _题目名称_pl/0编译器的扩充 _学生学院_计算机学院_ _专业班级_ 计算机科学与技术13(9)学 号 学生姓名 指导教师_林志毅_2016 年 1 月 2 日一、 已完成的内容:(1) 扩充赋值运算:*= 和 /=(2) 扩充语句(pascal的for语句)for :=step untildo(3) 增加类型: 字符类型; 实数类型。(4) 增加注释; 多行注释由/*和*/包含,单行注释为/ 二、 实验环境与工具(1)计算机及操作系统:pc机,windows7(2)程序设计语言:c+(3)使用软件borland c+ builder 6.0(4)教学型编译程序:pl/0三、 具体实现:1. 扩充赋值运算:*= 和 /=(1) 语法树表达式*=(/=,-=,+=)变量(2) 修改getsym()方法(写出修改的代码) else if(ch=*) getch(); if(ch=) sym=timesbecomes; getch(); else sym=times; else if(ch=/) getch(); if(ch=) sym=slashbecomes; getch(); (3) 修改statement()方法(写出修改的代码)case ident:i=position(id,tx);if (i=0) error(11);else if (tablei.kind=variable | tablei.kind=floattype) /*assignment to non-variable*/ getsym(); if (sym=becomes| sym=timesbecomes | sym=slashbecomes|sym=plusbecomes|sym=minusbecomes) relop=sym; if(sym!=becomes) /若为除等于(或其他类似符号)则先把符号左边的变量值放入栈中 gen(lod,lev-tablei.vp.level,tablei.vp.adr); getsym(); else error(13); expression(fsys,lev,tx); if(relop=timesbecomes) gen(opr,0,4); else if(relop=slashbecomes) gen(opr,0,5); else if(relop=plusbecomes) gen(opr,0,2); else if(relop=minusbecomes) gen(opr,0,3); gen(sto,lev-tablei.vp.level,tablei.vp.adr); (4) 运行测试(测试的pl0源码扩充单词的测试并贴运行结果截图)pl0源码:program ex01;var a,b,c,d;begin a:=16; a/=2; write(a); /结果为8 b:=4; b*=2; write(b); /结果为8 c:=6; c+=2; write(c); /结果为8 d:=10; d-=2; write(d); /结果为8end.(5) 运行结果:(6) 出现的问题及解决开始时在实现/=和*=操作时,*=的实现很顺利,而/=却一直没有得到理想的结果,通过与同学的讨论得知代码中除号指令的解析中,其实为除余操作,于是将%改为/,但是结果还是错误,经过调试发现是两个相除的数在栈中的位置相反了,正确的状态应该是除数位于次栈顶,而被除数位于栈顶。解决:在调用expression函数解析/=右边表达式前,先将其左边变量的值放入栈中。2. 扩充语句(pascal的for语句)for :=step untildo(1) 语法图(2) 修改getsym()方法(写出修改的代码)此处无修改,for、step、until及do等关键字已放置关键字数组中,通过该数组便可识别。(3) 修改statement()方法(写出修改的代码)case forsym: getsym(); statement(symsetunion(symsetnew(stepsym),fsys),lev,tx); /处理for后面的赋值语句 cx3=cx; gen(jmp,0,0); /用于第一次执行for语句时跳过step语句 cx1=cx; /记录step后语句的代码位置 if(sym=stepsym) getsym(); statement(symsetunion(symsetnew(untilsym),fsys),lev,tx); /处理step后面的表达式 else error(8); if(sym=untilsym) codecx3.a=cx; /回填第一次进入for循环时的直接跳转地址 getsym(); else error(8); condition(symsetadd(dosym, fsys),lev,tx); /处理条件语句 if(sym=dosym) getsym(); else error(8); cx2=cx; gen(jpc,0,0); /条件跳转,栈顶若为非真,则跳转到参数三位置,该位置待回填 statement(fsys,lev,tx); /处理do后面内容 gen(jmp,0,cx1); /执行完for语句内的语句则重新跳回step处 codecx2.a=cx; /回填条件跳转 break;(4) 运行测试pl0源码:program ex01;var a,sum;begin sum:=0; for a:=1 step a+=1 until a=0 & ch=0 & ch=0 & ch=9) /以下获取小数点后的值 j=0; m=(ch-0)*0.1; while(jlmax) error(30); /lmax为小数点后数字最大度 fprintf(fout,%f, num); (2) 修改block中的方法运行测试if (sym=charsym) getsym(); do chardeclaration(lev,tx,dx); while (sym=comma) getsym(); chardeclaration(lev,tx,dx); if (sym=semicolon) getsym(); else error(5); while(sym=ident);if (sym=floatsym) getsym(); do floatdeclaration(lev,tx,dx); while (sym=comma) getsym(); doubledeclaration(lev,tx,dx); if (sym=semicolon) getsym(); else error(5); while(sym=ident); (3) 修改statement中的方法case ident: getsym();i=position(id,tx);if (i=0) error(11);else if (tablei.kind=chartype | tablei.kind=variable | tablei.kind=floattype) /*assignment to non-variable*/if (sym=becomes | sym=timesbecomes | sym=slashbecomes | sym=plusbecomes| sym=minusbecomes) relop=sym; if(sym!=becomes) /若为除等于(或其他类似)。则先把符号左边的变量值放入栈中 gen(lod,lev-tablei.vp.level,tablei.vp.adr); getsym(); else error(13); expression(fsys,lev,tx); if(relop=timesbecomes) gen(opr,0,4); else if(relop=slashbecomes) gen(opr,0,5); else if(relop=plusbecomes) gen(opr,0,2); else if(relop=minusbecomes) gen(opr,0,3); gen(sto,lev-tablei.vp.level,tablei.vp.adr); else error(12); i=0; break;case writesym:/根据不同类型进行相应输出getsym();if (sym=lparen) do getsym();expression(symsetunion(symsetnew(rparen,comma),fsys),lev,tx); i=position(id,tx); switch (tablei.kind) case chartype:gen(opr,0,17); break; case floattype:gen(opr,0,18); break; default:gen(opr,0,14); while(sym=comma); if (sym!=rparen) error(sbnum); else getsym();gen(opr,0,15);break; /*writesym*/(4) 修改factor中的方法(包含字符的识别处理)while (symin(sym,facbegsys) if (sym=ident) i=position(id,tx); if (i=0) error(11); elseswitch (tablei.kind) case constant: gen(lit,0,tablei.val); break; case variable: gen(lod,lev-tablei.vp.level,tablei.vp.adr); break; case procedur: error(21); break; case floattype: gen(lod,lev-tablei.vp.level,tablei.vp.adr); break; case chartype: gen(lod,lev-tablei.vp.level,tablei.vp.adr); break; getsym(); else if (sym=number) if (numamax) error(31); num=0; gen(lit,0,num); getsym(); /将表达式中的数字置于栈顶 else if (sym=lparen) /左 括 号 getsym(); expression(symsetadd(rparen,fsys),lev,tx);if (sym=rparen) getsym();else error(22); else if (sym=character) gen(lit,0,num); /将字符放入栈顶 getsym(); (5) 修改enter中的方法case chartype: tabletx.vp.level=lev; tabletx.vp.adr=dx; dx+; break; case floattype: tabletx.vp.level=lev; tabletx.vp.adr=dx; dx+; break;(6) 在interpret指令opr中增加字符输出和实数输出case 17: form1-printcs(st); fprintf(fout,%cn,st); t-; /增加字符输出 break;case 18: form1-printrs(,st); fprintf(fout,%dn,st); t-; /增加实数型输出 break;(7) 其它修改1) 增加相应的关键字char和float;2) 由于增加实型,因此将模拟栈的数组类型改为double型;另目标指令结构体instruction中的a,及全局变量num也改为double型(8) 运行测试:pl0源码:program ex01;char a,b;float c,d,sum;begin a:=a; b:=b+2; write(a); write(b); write(b+2); c:=123.321; d:=321.123; sum:=c+d+0.0004; write(sum); end.(9) 运行结果:(10) 出现的问题及解决字符型的实现主要问题是在赋值、字符表达式的处理及输出三个方面。赋值刚开始没有思路,之后借鉴var型的赋值,才清楚需要使用到栈这个媒介进入赋值:先把字符值放入栈中,在将栈顶值传给字符型变量。而字符表达式的处理在factor里进行识别处理。关于输出则需要在writesym的识别处理中进行类型判断采取不同输出方式,并需新建一条指令专门用于字符输出实数型的实现主要问题为:1、数据获取:小数点后的值的获取需要用到循环帮助实现;2、变量更改:在没有引入实数型前,用来模拟栈的数组类型为int型,而引入后,则需要将其更改为实数型,在程序中与栈值有关的那些变量类型也同样改为实数型。4. 增加注释; 多行注释由/*和*/包含,单行注释为/ (1) 修改getsym()方法(写出修改的代码)else if(ch=/) getch(); if(ch=) sym=slashbecomes; getch(); else if(ch=*) getch(); i=ch; while(i!=* | ch!=/) i=ch; getch(); / form1-printcs(ch); if(i!=*&ch!=/) error(19); else getch();/不能忽略,为下一次调用getsym提供第一个字符,用于switch语句 getsym(); else if(ch=/) /单行注释功能 i=cx;/记录当前行 while(cc!=ll) getch(); /cc为当前字符在行中位置,ll为当前行的字数 getsym(); /滤去注释后继续获取后面的字符串 else sym=slash; (2) 运行测试pl0源码:program ex01;var a,sum;begin /*下面代码求解1到100的之间 每个整数的相加之和*/ sum:=0; for a:=1 step a+=1 until a=100 do /求1100的和sum+=a; write(sum); end.(3) 运行结
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年自考专业(金融)常考点试卷含答案详解【能力提升】
- 2024-2025学年度工程硕士模考模拟试题含答案详解【新】
- 2024年银行岗位试题及参考答案详解(夺分金卷)
- 2025无人机资格证模考模拟试题及答案详解(基础+提升)
- 2025自考专业(公共关系)考前冲刺练习题及完整答案详解(有一套)
- 2024安全员考试综合提升测试卷含答案详解【新】
- 土木工程建筑施工题库带答案详解(基础题)
- 美容化妆人员通关题库及参考答案详解(夺分金卷)
- 法律职业资格考试题库试题含答案详解(突破训练)
- 2024-2025学年度火电电力职业鉴定综合提升测试卷【基础题】附答案详解
- 生物质颗粒工人管理制度
- 【内蒙古】2024内蒙古事业单位联考考试笔试附带答案详解
- 生物医药公司采购管理制度
- 煤矿关联交易管理制度
- 器械UDI码管理制度
- 印章管理工作培训
- 园林养护班组管理制度
- 矿业公司股权转让与资源开发合作协议
- 司马懿的课件
- 2025年餐饮系统项目市场调查研究报告
- 2025年人教版高中物理必修3专项复习:电势差与电场强度的关系(解析版)
评论
0/150
提交评论