已阅读5页,还剩30页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
PL0.cpp#include pl0.h/*PL/0 语言编译程序,由江汉石油学院计算机系周云才根据清华大学出版社出版,*吕映芝,张素琴,蒋维杜编写的教材编译原理中第二章(PL/0编译程序的实现)*以及附录A中的代码改编而成。*代码版权由周云才拥有,使用者必须遵循以下约定:*可以免费使用此文件,但必须包含此声明。*可以修改、传播、打印、出版这里的源代码。*可以在任何软件工程中使用这里的源代码。* */ 错误字符串数组string PL0:errStr= ,error 0001: 常数说明中“=”写成“:=”,error 0002: 常数说明中的“=”后应为数字,error 0003: 常数说明中的标识符后应是“=”,error 0004: const,var,procedure后应为标识符,error 0005: 漏掉了,或;,error 0006: 过程说明后的符号不正确(应是语句开始符或过程开始符),error 0007: 应是语句开始符,error 0008: 过程体内语句部分的后跟符不正确,error 0009: 程序皆为丢了句号.,error 0010: 语句之间漏了;,error 0011: 标识符没说明,error 0012: 赋值语句中,赋值号左部标识符属性应是变量,error 0013: 赋值语句左部标识符应是赋值号:=,error 0014: call后应为标识符,error 0015: call后标识符属性应为过程,error 0016: 条件语句中丢了then,error 0017: 丢了end或;,error 0018: while型循环语句中丢了do,error 0019: 语句后的标识符不正确,error 0020: 应为关系运算符,error 0021: 表达式内标识符属性不能是过程,error 0022: 表达式中漏掉了右括号),error 0023: 因子后的非法符号,error 0024: 表达式开始符不能是此符号,error 0025: 文件在不该结束的地方结束了,error 0026: 结束符出现在不该结束的地方,error 0027: ,error 0028: ,error 0029: ,error 0030: ,error 0031: 数越界,error 0032: read语句括号中标识符不是变量,error 0033: else附近错误 ,error 0034: repeat附近错误; / PL0构造函数PL0:PL0(char* source,char*destination)listswitch=true,sourceEnd=false;strcpy(word1,begin); / 初始化存储保留字strcpy(word2,call);strcpy(word3,const); strcpy(word4,do);strcpy(word5,else);strcpy(word6,end);strcpy(word7,if);strcpy(word8,odd);strcpy(word9,procedure);strcpy(word10,read);strcpy(word11,repeat);strcpy(word12,then);strcpy(word13,until);strcpy(word14,var);strcpy(word15,while);strcpy(word16,write);wsym1= BEGINSYM; wsym2= CALLSYM; / 初始化保留字表中每一个保留字对应的symbol类型 wsym3= CONSTSYM; wsym4= DOSYM;wsym5= ELSESYM; wsym6= ENDSYM;wsym7= IFSYM; wsym8= ODDSYM;wsym9= PROCSYM; wsym10= READSYM; wsym11= REPEATSYM; wsym12= THENSYM;wsym13= UNTILSYM; wsym14= VARSYM; wsym15= WHILESYM; wsym16= WRITESYM; memset(code,0,sizeof(code);memset(ssym,0,100*sizeof(symbol);memset(table,0,sizeof(table);memset(line,0,sizeof(line);ssym+= PLUS; / 初始化一些符号对应的symbol类型表ssym-= MINUS;ssym*= TIMES;ssym/= SLASH;ssym(= LPAREN;ssym)= RPAREN;ssym= EQL;ssym,= COMMA;ssym.= PERIOD;ssym#= NEQ;ssym= GTR;ssym;= SEMICOLON;strcpy(mnemonicLIT, lit ); / 初始化类PCODE指令助记符表 strcpy(mnemonicOPR, opr );strcpy(mnemonicLOD, lod );strcpy(mnemonicSTO, sto );strcpy(mnemonicCAL, cal );strcpy(mnemonicINT, int );strcpy(mnemonicJMP, jmp );strcpy(mnemonicJPC, jpc );declbegsys.insert(CONSTSYM),declbegsys.insert(VARSYM),declbegsys.insert(PROCSYM); / 初始化声明开始符号集合 statbegsys.insert(BEGINSYM),statbegsys.insert(CALLSYM),statbegsys.insert(IFSYM),statbegsys.insert(WHILESYM); / 初始化表达式开始符号集合facbegsys.insert(IDENT),facbegsys.insert(NUMBER),facbegsys.insert(LPAREN); / 初始化项开始符号集合err= 0;cc= 0; / 行缓冲区指针cx= 0; / 代码分配指针,代码生成模块总在cx所指位置生成新的代码 ll= 0; / 行缓冲区长度ch= ; / last character read kk= al; / 引入此变量是出于程序性能考虑codeNo=0; / code line no.fin=fopen(source,r);fout=fopen(destination,w);/ 出错处理,打印出错位置和出错代码void PL0:error(int n)char s10;sprintf(s,第 %d 行:,codeNo);errorString.push_back(s+errStrn);err= err+1;/error count/error end/ 词法分析,读取一个单词 void PL0:getsym()if(sourceEnd)return;int i,j,k;while (ch = |ch=9)getch(); / cls space and tabif(isalpha(ch) / id or reserved wordk=0;memset(a,0,al+1);/ 检测一个单词长度doif (k = kk)kk = k;elsedoakk= ;kk= kk-1;while(kk k);strcpy(id,a);i= 1;j= norw;/ 判断是否是关键字(二分搜索)dok= (i+j) / 2;if(strcmp(id, wordk)=0)i= k+1;while(i j)sym= wsymk;elsesym= IDENT;else if(isdigit(ch) / numberk= 0;num= 0;sym= NUMBER;donum= 10 * num + ch - 0;k= k+1;getch();while(isdigit(ch);if(k nmax)error(30);else if (ch = :)getch();if( ch = =)sym= BECOMES;getch();elsesym= NUL;else if(ch = ) / extra stuff added to support )getch();if( ch = =)sym= GEQ;getch();elsesym= GTR;else / end of extra stuffsym= ssymch; / 其它符号的赋值getch();/ 漏掉空格,读取一个字符void PL0:getch()if(cc = ll)if(feof(fin)if(sym!=PERIOD)error(25);sourceEnd=true;return;cc= 0;fgets(line,lineLength,fin);codeNo+;ll=strlen(line);if(linell-1=10) ll-;ch= linecc;cc= cc+1;/ 生成目标代码,并送入目标程序区void PL0:gen(fct x,int y,int z)if (cx cxmax)coutlevmax)error(32);do if( sym = CONSTSYM) / 处理常量声明getsym();doconstdeclaration(tx,dx,lev);while (sym = COMMA)getsym();constdeclaration(tx,dx,lev);if (sym =SEMICOLON)getsym();elseerror(5);while(sym=IDENT);if( sym = VARSYM) / 处理变量声明getsym();dovardeclaration(tx,dx,lev);while( sym = COMMA)getsym();vardeclaration(tx,dx,lev);if( sym =SEMICOLON)getsym();elseerror(5);while(sym=IDENT);while( sym =PROCSYM) / 处理过程的声明getsym();if (sym =IDENT)enter(PROCEDURE,tx,dx,lev);getsym();elseerror(4);if( sym =SEMICOLON)getsym();elseerror(5);symset tmp = fsys;tmp.insert(SEMICOLON);block(lev+1,tx,tmp);if (sym = SEMICOLON)getsym();symset tmp = statbegsys;for(int i= IDENT;i=PROCSYM;i+)tmp.insert(symbol)i);test(tmp,fsys,6);elseerror(5);symset tmp=statbegsys;tmp.insert(IDENT);test(tmp,declbegsys,7);while(declbegsys.find(sym)!=declbegsys.end();codetabletx0.other.inOther.adr.a= cx;tabletx0.other.inOther.adr= cx; / start adr of codetabletx0.other.inOther.size=dx;cx0= cx;gen(INT,0,dx);symset tmp=statbegsys;for(int i=SEMICOLON;i amax)error(31);num=0;tabletx.other.val=num;break;case VARIABLE:tabletx.other.inOther.level=lev;tabletx.other.inOther.adr=dx;dx+;break;case PROCEDURE:tabletx.other.inOther.level=lev;break;case ARRAY:tabletx.other.inOther.size = lev;break;/enter end/ 查找标示符在名字表中的位置 int PL0:position(alfa id,int tx)/find identifier id in tableint i;strcpy(, id);i= tx;while (strcmp(,id)!=0)i-;return i;/position end/ 常量定义处理void PL0:constdeclaration(int&tx,int&dx,int lev)if(sym = IDENT) getsym(); if(sym=EQL&sym=BECOMES) if( sym =BECOMES) error(1);getsym();if( sym = NUMBER)enter(CONSTANT,tx,dx,lev);getsym();else error(2); elseerror(3);else error(4);/ constdeclaration end/ 变量说明处理void PL0:vardeclaration(int&tx,int&dx,int lev)if( sym = IDENT)enter(VARIABLE,tx,dx,lev);getsym();elseerror(4);/vardeclaration end/ 数组说明处理void PL0:arraydeclaration(int&tx,int&dx,int lev) int upscript=0,downscript=0;getsym();if(sym = NUMBER | sym = CONSTSYM)if(num = 0)upscript = num;getsym();else error(32);if(sym = COMMA)getsym();elseerror(32);if(sym = NUMBER | sym = CONSTSYM)downscript = num;getsym();if(sym != RPAREN)error(32);elseenter(ARRAY,tx,dx,downscript+1);getsym();/ 列出目标代码清单void PL0:listcode(int cx0)/list code generated for this blockint i;if(listswitch)for (i= cx0;icx;i+) cout i mnemoniccodei.f codei.l codei.aendl;/ listcode end/ 语句部分处理 void PL0:statement(symset fsys,int tx,int lev)if(sourceEnd)return;int i,cx1,cx2;if(sym =IDENT)i= position(id,tx);if (i = 0)error(11);else if (tablei.kind!=VARIABLE)error(12);i= 0;getsym();if(sym =BECOMES)getsym();elseerror(13);expression(fsys,tx,lev);if(sym != SEMICOLON)error(10);if( i!= 0)gen(STO,lev-tablei.other.inOther.level,tablei.other.inOther.adr);else if( sym = READSYM)getsym();if( sym!=LPAREN)error(34);elsedogetsym();if (sym=IDENT)i=position(id,tx);elsei=0;if( i=0 )error(35);elsegen(OPR,0,16);gen(STO,lev-tablei.other.inOther.level,tablei.other.inOther.adr);getsym();while(sym = COMMA);if (sym != RPAREN)error(33);while (fsys.find(sym)!=fsys.end() getsym();else getsym();else if( sym = WRITESYM )getsym();if (sym=LPAREN)dogetsym();symset tmp=fsys;for(int t=RPAREN;t=COMMA;t+)tmp.insert(symbol)t);expression(tmp,tx,lev);gen(OPR,0,14);while(sym=COMMA);if (sym!=RPAREN)error(33);elsegetsym();gen(OPR,0,15);else if( sym =CALLSYM)getsym();if( sym!=IDENT)error(14);elsei= position(id,tx);if (i = 0)error(11);else if (tablei.kind = PROCEDURE)gen(CAL,lev-tablei.other.inOther.level,tablei.other.inOther.adr);elseerror(15);getsym();else if( sym =IFSYM)getsym();symset tmp=fsys;for(int i = THENSYM;i= DOSYM;i+)tmp.insert(symbol)i);condition(tmp,tx,lev);if( sym = THENSYM)getsym();elseerror(16);cx1= cx;gen(JPC,0,0);tmp.insert(ELSESYM);statement(tmp,tx,lev);getsym();codecx1.a= cx;if(sym = ELSESYM) getsym(); cx2=cx; gen(JMP,0,0); codecx1.a=cx; statement(fsys,tx,lev); codecx2.a=cx;else if( sym =BEGINSYM)getsym();symset tmp=fsys;for(int i=SEMICOLON;i=ENDSYM;i+)tmp.insert(symbol)i);statement(tmp,tx,lev);tmp=statbegsys;tmp.insert(SEMICOLON);while( tmp.find(sym)!=tmp.end()if(sourceEnd)return;if (sym =SEMICOLON|sym =ENDSYM)getsym();else if(sym=PERIOD)error(26);getsym();elseerror(10);tmp=fsys;for(i=SEMICOLON;i=ENDSYM;i+)tmp.insert(symbol)i);if(sourceEnd)return;if(sym=ENDSYM)break;statement(tmp,tx,lev);if( sym =ENDSYM)getsym();else if(!sourceEnd)error(17);else if(sym =WHILESYM)cx1= cx; / 记下当前代码分配位置,这是while循环的开始位置getsym();symset tmp=fsys;tmp.insert(DOSYM);condition(tmp,tx,lev); cx2= cx; / 记下当前代码分配位置,这是while的do中的语句的开始位置gen(JPC,0,0);if(sym =DOSYM)getsym();elseerror(18);statement(fsys,tx,lev);gen(JMP,0,cx1);codecx2.a= cx;else if(sym = REPEATSYM)symset temp1, temp2;temp1= fsys,temp1.insert(SEMICOLON),temp1.insert(UNTILSYM);cx1= cx;getsym();statement(temp1,tx,lev);temp2 = statbegsys;temp2.insert(SEMICOLON);while(temp2.find(sym) != temp2.end()if(sym = SEMICOLON)getsym();else error(34);statement(temp1,tx,lev);if(sym = UNTILSYM)getsym();condition(fsys,tx,lev);gen(JPC,0,cx1);elseerror(34); symset setT;test(fsys,setT,19);/statement end/ 表达式处理 void PL0:expression(symset fsys,int tx,int lev)symbol addop;symset tmp=fsys;for(int t=PLUS;t=PLUS&sym=PLUS&sym=MINUS)addop= sym;getsym();term(tmp,tx,lev);if (addop =PLUS)gen(OPR,0,2);elsegen(OPR,0,3);/ expression end/ 项处理void PL0:term(symset fsys,int tx,int lev)if(sourceEnd)return;symbol mulop;symset tmp=fsys;for(int t=TIMES;t=TIMES & symamax)error(31);num= 0;gen(LIT,0,num);getsym();else if( sym =LPAREN)getsym();symset tmp=fsys;tmp.insert(RPAREN);expression(tmp,tx,lev);if (sym = RPAREN)getsym();elseerror(22);test(fsys,facbegsys,23);/factor end/ 条件处理void PL0:condition(symset fsys,int tx,int lev)symbol relop;symset tmp=fsys;tmp.insert(EQL),tmp.insert(NEQ),tmp.insert(LSS),tmp.insert(LEQ),tmp.insert(GTR),tmp.insert(GEQ); if( sym = ODDSYM)getsym();expression(fsys,tx,lev);gen(OPR,0,6);elseexpression(tmp,tx,lev);if(tmp.find(sym)=tmp.end()error(20);elserelop= sym;getsym();expression(fsys,tx,lev);switch(relop)case EQL: gen(OPR,0,8);break;case NEQ: gen(OPR,0,9);break;case LSS: gen(OPR,0,10);break;case GEQ: gen(OPR,0,11);break;case GTR: gen(OPR,0,12);break;case LEQ: gen(OPR,0,13);break;/condition end/ 对目标代码的解释执行程序 void PL0:interpret()int err1=errorString.size();if(err10)cout存在%d个错误:err1endl;for(int i=0;ierr1;i+)couterrorStringiendl;/return;const int stacksize = 500;int p=0,b=1,t=0;/program-,base-,topstack-registersinstruction i;/ instruction registerint sstacksize+1=0;/ datastorecout Start PL/0n;doi= codep;p= p+1;switch(i.f)case LIT:t= t+1;st= i.a;break;case OPR:switch(i.a) /operatorcase 0:/ returnt= b-1; p= st+3; b= st+2;break;case 1:st= -st;break;case 2:t= t-1;st= st+st+1;break;case 3:t= t-1;st= st-st+1;break;case 4:t= t-1;st= st*st+1;break;case 5:t= t-1;st= st / st+1;break;case 6:if(st%2)st=1;elsest=0;break;case 8:t= t-1;if(st=st+1)st=1;elsest=0;break;case 9:t= t-1;if(st=st+1)st=0;elsest=1;break;case 10:t= t-1;if(st=st+1)st= 1;elsest=0;break;case 12:t= t-1;if(stst+1)st= 1;elsest=0;break;case 13:t= t-1;if(st=st+1)st= 1;elsest=0;b
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026年对标分析报告
- 2026年动物饲料益生菌行业发展趋势及投资前景预测报告
- 2026年吊篮专项施工方案(完整版)
- 企业信息技术应用方案
- 一级建造师公路工程专业培训教材
- 平台管理员的自我管理与时间管理
- 网站开发人员项目计划与技术开发路线
- 2026年中国复合斜切锯行业市场规模及投资前景预测分析报告
- 2025中国智能仓储系统集成及自动化升级与投资效益评估报告
- 2025中国智慧零售解决方案分析及市场增长潜力研究报告
- 税收咨询报告模板
- 上海市住宅修缮施工资料及表式
- (6)-1.2药物递送系统药剂学
- 有限空间作业安全知识考试试卷
- 金平福源矿业有限公司田房锡矿采矿权出让收益评估报告
- 一级注册消防工程师题库
- YC/T 145.7-1998烟用香精标准样品的确定和保存
- 第1章大气科学概论(南京信息工程大学大气概论)
- GB 17498.7-2008固定式健身器材第7部分:划船器附加的特殊安全要求和试验方法
- 2021年《中国近现代史纲要》说课2课件
- 岩土专业软件的区别
评论
0/150
提交评论