编译原理(PL0编译程序源代码_第1页
编译原理(PL0编译程序源代码_第2页
编译原理(PL0编译程序源代码_第3页
编译原理(PL0编译程序源代码_第4页
编译原理(PL0编译程序源代码_第5页
已阅读5页,还剩16页未读 继续免费阅读

下载本文档

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

文档简介

1、/*PL/0编译程序(C语言版)*编译和运行环境:*Visual C+6.0*WinXP/7*使用方法:*运行后输入PL/0源程序文件名*回答是否将虚拟机代码写入文件*回答是否将符号表写入文件*执行成功会产生四个文件 (词法分析结果.txt符号表.txt虚拟代码.txt源程序和地址.txt)*/ #include #includepl0.h#includestring#define stacksize 500/解释执行时使用的栈int main()bool nxtlevsymnum;printf(请输入源程序文件名:);scanf(%s,fname);fin=fopen(fname,r);/以

2、只读方式打开pl0源程序文件cifa=fopen(词法分析结果.txt,w);fa1=fopen(源程序和地址.txt,w);/输出源文件 及各行对应的首地址fprintf(fa1,输入pl0源程序文件名:);fprintf(fa1,%sn,fname);if(fin)printf(是否将虚拟机代码写入文件?(Y/N);/是否输出虚拟机代码scanf(%s,fname);listswitch=(fname0=y|fname0=Y); printf(是否将符号表写入文件?(Y/N);/是否输出符号表scanf(%s,fname);tableswitch=(fname0=y|fname0=Y);i

3、nit();/初始化err=0;cc=cx=ll=0;ch= ;if(-1!=getsym()fa=fopen(虚拟代码.txt,w);fas=fopen(符号表.txt,w);addset(nxtlev,declbegsys,statbegsys,symnum);nxtlevperiod=true;if(-1=block(0,0,nxtlev)/调用编译程序fclose(fa);fclose(fa1);fclose(fas);fclose(fin);return 0;if(sym!=period)error(9);/结尾丢失了句号if(err!=0)printf(pl0源程序出现错误,退出编

4、译!请从第一个错误处开始修改.nn);fprintf(cifa,源程序出现错误,请检查!);fprintf(fa1,源程序出现错误,请检查!);fprintf(fa,源程序出现错误,请检查!);fprintf(fas,源程序出现错误,请检查!);fclose(fa);fclose(fa1); fclose(fas);fclose(fin);elseprintf(Cant open file!n); fclose(cifa);/printf(n);return 0;void init()/初始化int i;for(i=0;i=255;i+)ssymi=nul;/设置单字符符号ssym+=plus

5、;ssym-=minus;ssym*=times;ssym/=slash;ssym(=lparen;ssym)=rparen; ssym=eql;ssym,=comma;ssym.=period;ssym#=neq;ssym;=semicolon;strcpy(&(word00),begin);/保留字设置,以字母顺序排列 便于折半查找strcpy(&(word10),call);strcpy(&(word20),const);strcpy(&(word30),do);strcpy(&(word40),end);strcpy(&(word50),if);strcpy(&(word60),odd

6、);strcpy(&(word70),procedure);strcpy(&(word80),read);strcpy(&(word90),then);strcpy(&(word100),var);strcpy(&(word110),while);strcpy(&(word120),write);wsym0=beginsym;/设置保留字类别 一字即一类wsym1=callsym;wsym2=constsym;wsym3=dosym;wsym4=endsym;wsym5=ifsym;wsym6=oddsym;wsym7=procsym;wsym8=readsym;wsym9=thensym;w

7、sym10=varsym;wsym11=whilesym;wsym12=writesym;strcpy(&(mnemoniclit0),lit);/设置指令名称strcpy(&(mnemonicopr0),opr);strcpy(&(mnemoniclod0),lod);strcpy(&(mnemonicsto0),sto);strcpy(&(mnemoniccal0),cal);strcpy(&(mnemonicinte0),int);strcpy(&(mnemonicjmp0),jmp);strcpy(&(mnemonicjpc0),jpc); for(i=0;isymnum;i+)/设置

8、符号集declbegsysi=false;statbegsysi=false;facbegsysi=false;declbegsysconstsym=true;/设置声明开始符号集declbegsysvarsym=true;declbegsysprocsym=true;statbegsysbeginsym=true;/设置语句开始符号集statbegsyscallsym=true;statbegsysifsym=true;statbegsyswhilesym=true;facbegsysident=true;/设置因子开始符号集facbegsysnumber=true;facbegsyslpa

9、ren=true;/用数组实现集合的集合运算int inset(int e,bool* s)return se;int addset(bool*sr,bool* s1,bool* s2,int n)int i;for(i=0;i=a&ch=z)/以字母开头的为保留字或者标识符k=0,l=1;doif(k=a&ch=0&ch=9);ak=0;/末尾存零strcpy(id,a);i=0;j=norw-1;do/开始折半查找k=(i+j)/2;if(strcmp(id,wordk)=0)i=k+1;while(ij)/找到 即为保留字 sym=wsymk; fprintf(cifa,%stt%ssy

10、mn,id,id);/printf(%stt%ssymn,id,id);else/否则为标识符或数字sym=ident;fprintf(cifa,%sttidentn,id);/printf(%sttidentn,id);else if(ch=0&ch=0&chnmax)/数字的长度限制fprintf(cifa,0ttnumbern);num=0;error(31);elsefprintf(cifa,%dttnumbern,num);/printf(%dttnumbern,num);elseif(ch=:)/检测赋值符号,:只能和=匹配,否则不能识别getchdo;if(ch=)sym=bec

11、omes;fprintf(cifa,:=ttbecomesn);getchdo;elsesym=nul;elseif(ch=)getchdo;if(ch=)sym=leq;/小于等于fprintf(cifa,=ttleqn);getchdo;elsesym=lss;/小于fprintf(cifa,)getchdo;if(ch=)sym=geq;/大于等于fprintf(cifa,=ttgeqn);getchdo;elsesym=gtr;/大于fprintf(cifa,ttgtrn);elsesym=ssymch;/不满足上述条件时 按单字/符处理switch(ch)case+:fprintf(

12、cifa,%cttplusn,ch);break;case -:fprintf(cifa,%cttminusn,ch);break;case *:fprintf(cifa,%ctttimesn,ch);break;case /:fprintf(cifa,%cttslashn,ch);break;case (:fprintf(cifa,%cttlparenn,ch);break;case ):fprintf(cifa,%cttrparenn,ch);break;case =:fprintf(cifa,%ctteqln,ch);break;case ,:fprintf(cifa,%cttcomma

13、n,ch);break;case #:fprintf(cifa,%cttneqn,ch);break;case ;:fprintf(cifa,%cttsemicolonn,ch);break;case .:break;default :error(26);if(sym!=period)/判断是否结束getchdo;elseprintf(n); fprintf(cifa,.ttperiodn);return 0;/生成目标代码/目标代码的功能码,层差和位移量int gen(enum fct x,int y,int z)if(cx=cxmax)/如果目标代码索引过大,报错 printf(Progr

14、am too long);return -1;codecx.f=x;codecx.l=y;codecx.a=z;cx+;return 0;/测试字符串int test(bool* s1,bool* s2,int n)if(!inset(sym,s1)/测试sym是否属于s1,不属于则报错nerror(n);while(!inset(sym,s1)&(!inset(sym,s2)/检测不通过时,不停获得符号,直到它属于需要或补救的集合getsymdo;return 0;/编译程序主体/lev:当前分程序所在层,tx:名字表当前尾指针fsys:当前模块 后跟符号集合int block(int le

15、v,int tx,bool* fsys)int i;int dx;/名字分配到的相对地址int tx0;/保留初始txint cx0;/保留初始cxbool nxtlevsymnum;dx=3;/相对地址从3开始,前3个单元即0、1、2单元分别为 SL:静态链;/DL:动态链;RA:返回地址tx0=tx;/记录本层的初始位置tabletx.adr=cx;gendo(jmp,0,0);if(levlevmax)/层数超过3error(32);doif(sym=constsym)/收到常量声明printf(该语句为常量定义语句n);getsymdo;doconstdeclarationdo(&tx

16、,lev,&dx);/常量声明处理,dx会改/变 所以使用指针while(sym=comma)/处理一次多常量定义getsymdo;constdeclarationdo(&tx,lev,&dx);if(sym=semicolon)/常量声明处理结束getsymdo;elseerror(5);/漏掉了逗号或者分号(一般是分号)while(sym=ident);if(sym=varsym)/收到变量声明printf(该语句为变量声明语句n);getsymdo;dovardeclarationdo(&tx,lev,&dx);/变量声明处理while(sym=comma)/处理一次多变量定义getsy

17、mdo;vardeclarationdo(&tx,lev,&dx);if(sym=semicolon)/变量声明处理结束getsymdo;elseerror(5);/漏掉逗号或者分号while(sym=ident);while(sym=procsym)/收到过程声明printf(该语句为过程声明语句n);getsymdo;if(sym=ident)enter(procedur,&tx,lev,&dx);/记录过程名getsymdo;elseerror(4);/过程声明后应为标识符if(sym=semicolon)getsymdo;elseerror(5);/漏掉了分号memcpy(nxtlev

18、,fsys,sizeof(bool)*symnum);nxtlevsemicolon=true;if(-1=block(lev+1,tx,nxtlev)return -1;if(sym=semicolon)getsymdo;memcpy(nxtlev,statbegsys,sizeof(bool)*symnum);nxtlevident=true;nxtlevprocsym=true;testdo(nxtlev,fsys,6);elseerror(5);memcpy(nxtlev,statbegsys,sizeof(bool)*symnum);nxtlevident=true;nxtlevpe

19、riod=true;testdo(nxtlev,declbegsys,7);while(inset(sym,declbegsys);/直到没有声明符号codetabletx0.adr.a=cx;/开始生成当前过程代码tabletx0.adr=cx;/当前过程代码地址tabletx0.size=dx;cx0=cx;gendo(inte,0,dx);/生成分配内存代码if(tableswitch)/输出符号表if(tx0+1tx)fprintf(fas,TABLE:n);/printf(NULLn);for(i=tx0+1;iamax)error(31);num=0; table(*ptx).val=num; break;case variable:table(*ptx).level=lev;table(*ptx).adr=(*pdx);(*pdx)+;break;case procedur:table(*ptx).level=lev;break;/寻找符号在符号表中的地址int position(char*idt,int tx)int i;strcpy(,idt);i=tx;/符号表尾while(strcmp(,idt)!=0)i-;return i;/常量声明处理int constdeclaration(in

温馨提示

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

评论

0/150

提交评论