编译原理(PL0编译程序源代码

上传人:good****022 文档编号:116375025 上传时间:2022-07-05 格式:DOCX 页数:21 大小:43.01KB
返回 下载 相关 举报
编译原理(PL0编译程序源代码_第1页
第1页 / 共21页
编译原理(PL0编译程序源代码_第2页
第2页 / 共21页
编译原理(PL0编译程序源代码_第3页
第3页 / 共21页
点击查看更多>>
资源描述
/*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);/以只读方式打开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);init();/初始化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源程序出现错误,退出编译!请从第一个错误处开始修改.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;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);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;wsym10=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+)/设置符号集declbegsysi=false;statbegsysi=false;facbegsysi=false;declbegsysconstsym=true;/设置声明开始符号集declbegsysvarsym=true;declbegsysprocsym=true;statbegsysbeginsym=true;/设置语句开始符号集statbegsyscallsym=true;statbegsysifsym=true;statbegsyswhilesym=true;facbegsysident=true;/设置因子开始符号集facbegsysnumber=true;facbegsyslparen=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%ssymn,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=becomes;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(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,%cttcomman,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(Program 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 lev,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,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)/处理一次多变量定义getsymdo;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,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;nxtlevperiod=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(table0.name,idt);i=tx;/符号表尾while(strcmp(tablei.name,idt)!=0)i-;return i;/常量声明处理int constdeclaration(int* ptx,int lev,int* pdx)if(sym=ident)getsymdo;if(sym=eql|sym=becomes)if(sym=becomes)error(1);getsymdo;if(sym=number)enter(constant,ptx,lev,pdx);getsymdo;elseerror(2);elseerror(3);elseerror(4);return 0;/变量声明处理int vardeclaration (int* ptx,int lev,int* pdx)if(sym=ident)enter(variable,ptx,lev,pdx);getsymdo;elseerror(4);return 0;/输出目标代码清单void listcode(int cx0)int i;if(listswitch)for(i=cx0;iamax)error(31);num=0;gendo(lit,0,num);getsymdo;elseif(sym=lparen)getsymdo;memcpy(nxtlev,fsys,sizeof(bool)*symnum);nxtlevrparen=true;expressiondo(nxtlev,ptx,lev);if(sym=rparen)getsymdo;elseerror(22);testdo(fsys,facbegsys,23);return 0;int condition(bool* fsys,int* ptx,int lev)e
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 压缩资料 > 预防医学


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!