/*PL/0编译程序(C语言版)*编译和运行环境:*VisualC++6.0*WinXP/7*使用方法:*运行后输入PL/0源程序文件名*回答是否将虚拟机代码写入文件*回答是否将符号表写入文件*执行成功会产生四个文件(词法分析结果.txt符号表.txt虚拟代码.txt源程序和地址.txt)*/#includestdio.h#includepl0.h#includestring#definestacksize500//解释执行时使用的栈intmain(){boolnxtlev[symnum];printf(请输入源程序文件名:);scanf(%s,fname);fin=fopen(fname,r);//以只读方式打开pl0源程序文件cifa=fopen(词法分析结果.txt,w);fa1=fopen(源程序和地址.txt,w);//输出源文件及各行对应的首地址fprintf(fa1,输入pl0源程序文件名:);fprintf(fa1,%s\n,fname);if(fin){printf(是否将虚拟机代码写入文件?(Y/N));//是否输出虚拟机代码scanf(%s,fname);listswitch=(fname[0]=='y'||fname[0]=='Y');printf(是否将符号表写入文件?(Y/N));//是否输出符号表scanf(%s,fname);tableswitch=(fname[0]=='y'||fname[0]=='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);nxtlev[period]=true;if(-1==block(0,0,nxtlev)){//调用编译程序fclose(fa);fclose(fa1);fclose(fas);fclose(fin);return0;}if(sym!=period){error(9);//结尾丢失了句号}if(err!=0){printf(pl0源程序出现错误,退出编译!!!请从第一个错误处开始修改.\n\n);fprintf(cifa,源程序出现错误,请检查!!!);fprintf(fa1,源程序出现错误,请检查!!!);fprintf(fa,源程序出现错误,请检查!!!);fprintf(fas,源程序出现错误,请检查!!!);}fclose(fa);fclose(fa1);fclose(fas);}fclose(fin);}else{printf(Can'topenfile!\n);}fclose(cifa);//printf(\n);return0;}voidinit(){//初始化inti;for(i=0;i=255;i++)ssym[i]=nul;//设置单字符符号ssym['+']=plus;ssym['-']=minus;ssym['*']=times;ssym['/']=slash;ssym['(']=lparen;ssym[')']=rparen;ssym['=']=eql;ssym[',']=comma;ssym['.']=period;ssym['#']=neq;ssym[';']=semicolon;strcpy(&(word[0][0]),begin);//保留字设置,以字母顺序排列便于折半查找strcpy(&(word[1][0]),call);strcpy(&(word[2][0]),const);strcpy(&(word[3][0]),do);strcpy(&(word[4][0]),end);strcpy(&(word[5][0]),if);strcpy(&(word[6][0]),odd);strcpy(&(word[7][0]),procedure);strcpy(&(word[8][0]),read);strcpy(&(word[9][0]),then);strcpy(&(word[10][0]),var);strcpy(&(word[11][0]),while);strcpy(&(word[12][0]),write);wsym[0]=beginsym;//设置保留字类别一字即一类wsym[1]=callsym;wsym[2]=constsym;wsym[3]=dosym;wsym[4]=endsym;wsym[5]=ifsym;wsym[6]=oddsym;wsym[7]=procsym;wsym[8]=readsym;wsym[9]=thensym;wsym[10]=varsym;wsym[11]=whilesym;wsym[12]=writesym;strcpy(&(mnemonic[lit][0]),lit);//设置指令名称strcpy(&(mnemonic[opr][0]),opr);strcpy(&(mnemonic[lod][0]),lod);strcpy(&(mnemonic[sto][0]),sto);strcpy(&(mnemonic[cal][0]),cal);strcpy(&(mnemonic[inte][0]),int);strcpy(&(mnemonic[jmp][0]),jmp);strcpy(&(mnemonic[jpc][0]),jpc);for(i=0;isymnum;i++){//设置符号集declbegsys[i]=false;statbegsys[i]=false;facbegsys[i]=false;}declbegsys[constsym]=true;//设置声明开始符号集declbegsys[varsym]=true;declbegsys[procsym]=true;statbegsys[beginsym]=true;//设置语句开始符号集statbegsys[callsym]=true;statbegsys[ifsym]=true;statbegsys[whilesym]=true;facbegsys[ident]=true;//设置因子开始符号集facbegsys[number]=true;facbegsys[lparen]=true;}//用数组实现集合的集合运算intinset(inte,bool*s){returns[e];}intaddset(bool*sr,bool*s1,bool*s2,intn){inti;for(i=0;in;i++)sr[i]=s1[i]||s2[i];return0;}voiderror(intn){//出错处理,打印出错位置和错误编码charspace[81];memset(space,32,81);space[cc-1]=0;printf(error(%d),n);fprintf(fa1,error(%d),n);switch(n){case1:printf(\t\t常量说明中的“=”写成“:=”\n);fprintf(fa1,\t\t常量说明中的“=”写成“:=”\n);break;case2:printf(\t\t常量说明中的=后应该是数字\n);fprintf(fa1,\t\t常量说明中的=后应该是数字\n);break;case3:printf(\t\t常量说明符中的表示符应该是=\n);fprintf(fa1,\t\t常量说明符中的表示符应该是=\n);break;case4:printf(\t\tconst,var,procedure后应为标识符\n);fprintf(fa1,\t\tconst,var,procedure后应为标识符\n);break;case5:printf(\t\t漏掉了“,”或“;”\n);fprintf(fa1,\t\t漏掉了“,”或“;”\n);break;case6:printf(\t\t过程说明后的符号不正确\n);fprintf(fa1,\t\t过程说明后的符号不正确\n);break;case7:printf(\t\t应是语句开始符\n);fprintf(fa1,\t\t应是语句开始符\n);break;case8:printf(\t\t程序体内语句部分的后跟符不正确\n);fprintf(fa1,\t\t程序体内语句部分的后跟符不正确\n);break;case9:printf(\t\t程序结尾丢了句号“.”\n\n);fprintf(fa1,\t\t程序结尾丢了句号“.”\n);break;case10:printf(\t\t语句之间漏了“;”\n);fprintf(fa1,\t\t语句之间漏了“;”\n);break;case11:printf(\t\t标识符拼写错误或未说明\n);fprintf(fa1,\t\t标识符拼写错误或未说明\n);break;case12:printf(\t\t赋值语句中,赋值号左部标识符属性应是变量\n);fprintf(fa1,\t\t赋值语句中,赋值号左部标识符属性应是变量\n);break;case13:printf(\t\t赋值语句左部标识符后应是复制号“:=”\n);fprintf(fa1,\t\t赋值语句左部标识符后应是复制号“:=”\n);break;case14:printf(\t\tcall后应为标识符\n);fprintf(fa1,\t\tcall后应为标识符\n);break;case15:printf(\t\tcall后标识符属性应为过程\n);fprintf(fa1,\t\tcall后标识符属性应为过程\n);break;case16:printf(\t\t条件语句中丢了then\n);fprintf(fa1,\t\t条件语句中丢了then\n);break;case17:printf(\t\t丢了“end”或“;”\n);fprintf(fa1,\t\t丢了“end”或“;”\n);break;case18:printf(\t\twhile型循环语句中丢了“do”\n);fprintf(fa1,\t\twhile型循环语句中丢了“do”\n);break;case19:printf(\t\t语句后的符号不正确\n);fprintf(fa1,\t\t语句后的符号不正确\n);break;case20:printf(\t\t应为关系运算符\n);fprintf(fa1,\t\t应为关系运算符\n);break;case21:printf(\t\t表达式内标示符属性不能是过程\n);fprintf(fa1,\t\t表达式内标示符属性不能是过程\n);break;case22:printf(\t\t表达式漏掉了右括号\n);fprintf(fa1,\t\t表达式漏掉了右括号\n);break;case23:printf(\t\t因子后的非法符号\n);fprintf(fa1,\t\t因子后的非法符号\n);break;case24:printf(\t\t表达式的开始符不能是此符号\n);fprintf(fa1,\t\t表达式的开始符不能是此符号\n);break;case25:printf(\t\t标识符越界\n);fprintf(fa1,\t\t标识符越界\n);break;case26:printf(\t\t非法字符\n);fprintf(fa1,\t\t非法字符\n);break;case31:printf(\t\t数越界\n);fprintf(fa1,\t\t数越界\n);break;case32:printf(\t\tread语句括号中的标识符不是变量\n);fprintf(fa1,\t\tread语句括号中的标识符不是变量\n);break;case33:printf(\t\twrite()或read()中应为完整表达式\n);fprintf(fa1,\