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

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

编译原理(PL0编译程序源代码)
/*PL/0编译程序(C语言版)
*编译和运行环境:
*Visual C++6.0
*WinXP/7
*使用方法:
*运行后输入PL/0源程序文件名
*回答是否将虚拟机代码写入文件
*回答是否将符号表写入文件
*执行成功会产生四个文件(词法分析结果.txt符号表.txt虚拟代码.txt源程序和地址.txt)
*/
#include
#include"pl0.h"
#include"string"
#define stacksize 500//解释执行时使用的栈
int main(){
bool nxtlev[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);
return 0;
}
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't open file!\n");
}
fclose(cifa);//printf("\n");
return 0;
}
void init(){//初始化
int i;
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;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;
}//用数组实现集合的集合运算
int inset(int e,bool* s){
return s[e];
}
int addset(bool*sr,bool* s1,bool* s2,int n){
int i;
for(i=0;i<n;i++)< p="">
sr[i]=s1[i]||s2[i];
return 0;
}
void error(int n){//出错处理,打印出错位置和错误编码char space[81];
memset(space, 32,81);
space[cc-1]=0;
printf("error(%d)",n);
fprintf(fa1,"error(%d)",n);
switch(n){
case 1:
printf("\t\t常量说明中的“=”写成“:=”\n"); fprintf(fa1,"\t\t常量说明中的“=”写成“:=”\n"); break;
case 2:
printf("\t\t常量说明中的=后应该是数字\n"); fprintf(fa1,"\t\t常量说明中的=后应该是数字\n"); break;
case 3:
printf("\t\t常量说明符中的表示符应该是=\n" ); fprintf(fa1,"\t\t常量说明符中的表示符应该是=\n"); break;
case 4:
printf("\t\tconst,var,procedure后应为标识符\n" ); fprintf(fa1,"\t\tconst,var,procedure后应为标识符\n");
break;
case 5:
printf("\t\t漏掉了“,”或“;”\n" );
fprintf(fa1,"\t\t漏掉了“,”或“;”\n" );
break;
case 6:
printf("\t\t过程说明后的符号不正确\n" );
fprintf(fa1,"\t\t过程说明后的符号不正确\n"); break;
case 7:
printf("\t\t应是语句开始符\n" );
fprintf(fa1,"\t\t应是语句开始符\n" );
case 8:
printf("\t\t程序体语句部分的后跟符不正确\n" );
fprintf(fa1,"\t\t程序体语句部分的后跟符不正确\n" );
break;
case 9:
printf("\t\t程序结尾丢了句号“.”\n\n" );
fprintf(fa1,"\t\t程序结尾丢了句号“.”\n");
break;
case 10:
printf("\t\t语句之间漏了“;”\n" );
fprintf(fa1,"\t\t语句之间漏了“;”\n");
break;
case 11:
printf("\t\t标识符拼写错误或未说明\n" );
fprintf(fa1,"\t\t标识符拼写错误或未说明\n");
break;
case 12:
printf("\t\t赋值语句中,赋值号左部标识符属性应是变量\n" );
fprintf(fa1,"\t\t赋值语句中,赋值号左部标识符属性应是变量\n");
break;
case 13:
printf("\t\t赋值语句左部标识符后应是复制号“:=”\n" );
fprintf(fa1,"\t\t赋值语句左部标识符后应是复制号“:=”\n");
break;
case 14:
printf("\t\tcall后应为标识符\n" );
fprintf(fa1,"\t\tcall后应为标识符\n");
break;
printf("\t\tcall后标识符属性应为过程\n" );
fprintf(fa1,"\t\tcall后标识符属性应为过程\n"); break;
case 16:
printf("\t\t条件语句中丢了then\n" );
fprintf(fa1,"\t\t条件语句中丢了then\n"); break;
case 17:
printf("\t\t丢了“end”或“;”\n" );
fprintf(fa1,"\t\t丢了“end”或“;”\n"); break;
case 18:
printf("\t\twhile型循环语句中丢了“do”\n" ); fprintf(fa1,"\t\twhile型循环语句中丢了“do”\n"); break;
case 19:
printf("\t\t语句后的符号不正确\n" );
fprintf(fa1,"\t\t语句后的符号不正确\n" ); break;
case 20:
printf("\t\t应为关系运算符\n" );
fprintf(fa1,"\t\t应为关系运算符\n");
break;
case 21:
printf("\t\t表达式标示符属性不能是过程\n" ); fprintf(fa1,"\t\t表达式标示符属性不能是过程\n"); break;
case 22:
printf("\t\t表达式漏掉了右括号\n" );
fprintf(fa1,"\t\t表达式漏掉了右括号\n");
break;
case 23:
printf("\t\t因子后的非法符号\n" );
fprintf(fa1,"\t\t因子后的非法符号\n");
break;
case 24:
printf("\t\t表达式的开始符不能是此符号\n" );
fprintf(fa1,"\t\t表达式的开始符不能是此符号\n"); break;
case 25:
printf("\t\t标识符越界\n" );
fprintf(fa1,"\t\t标识符越界\n");
break;
case 26:
printf("\t\t非法字符\n" );
fprintf(fa1,"\t\t非法字符\n");
break;
case 31:
printf("\t\t数越界\n");
fprintf(fa1,"\t\t数越界\n");
break;
case 32:
printf("\t\tread语句括号中的标识符不是变量\n" ); fprintf(fa1,"\t\tread语句括号中的标识符不是变量\n"); break;
case 33:
printf("\t\twrite()或read()中应为完整表达式\n" ); fprintf(fa1,"\t\twrite()或read()中应为完整表达式\n"); break;
default:
printf("\t\t出现未知错误\n" );
fprintf(fa1,"\t\t出现未知错误\n");
}err++;
}
//漏掉空格,读取一个字符,每次读一行,存入line缓冲区,line 被getsym取空后再读一//行,被函数getsym调用
int getch(){
if(cc==ll){
if(feof(fin)){
printf("program incomplete");
return-1;
}
ll=0;
cc=0;
printf("\n%d ",cx);
fprintf(fa1,"\n%d ",cx);
ch=' ';
while(ch!=10){
if(EOF==fscanf(fin,"%c",&ch)){
line[ll]=0;
break;
}printf("%c",ch);
fprintf(fa1,"%c",ch);
line[ll]=ch;
ll++;
}fprintf(cifa,"\n");
}
ch=line[cc];
cc++;
return 0;
}
int getsym(){//词法分析int i,j,k,l;
</n;i++)<>。

相关文档
最新文档