PL0源程序编译原理实验代码.docx
- 文档编号:4387208
- 上传时间:2022-12-01
- 格式:DOCX
- 页数:26
- 大小:20.07KB
PL0源程序编译原理实验代码.docx
《PL0源程序编译原理实验代码.docx》由会员分享,可在线阅读,更多相关《PL0源程序编译原理实验代码.docx(26页珍藏版)》请在冰豆网上搜索。
PL0源程序编译原理实验代码
附件1小组成员:
程序清单
Main.c
#include
#include
#include
voiderror(intn);
voidgetsym();
//voidenter(enumobjectk,int*ptx,intlev,int*pdx);
intposition(char*idt,inttx);
intconstdeclaration(int*ptx,intlev,int*pdx);
intvardeclaration(int*ptx,intlev,int*pdx);
intfactor(int*ptx,intlev);
intterm(int*ptx,intlev);
intexpression(int*ptx,intlev);
intstatement(int*ptx,intlev);
intblock();
enumobject{constant,variable,procedure};
structtab{charname[14];
enumobjectkind;
intval;
intlevel;
intadr;
intsize;
}table[100];
enumsymbol{
nul,ident,number,plus,minus,times,slash,oddsym,eql,neq,lss,leq,gtr,geq,lparen,rparen,comma,semicolon,
period,becomes,beginsym,endsym,ifsym,thensym,whilesym,writesym,readsym,dosym,callsym,constsym,varsym,
procsym,progsym,};
enumsymbolsym=nul;
enumsymbolmulop;
enumsymbolwsym[14];
enumsymbolssym[256];
charch='';
char*str;
charword[14][10]={"begin","call","const","do","end","if","odd","procedure","program","read","then","var","while","write"};//设置保留字名字
intnum;
intlev=0;
inttx=0;
intk;
int*mm;
//=(int*)malloc(sizeof(int));
char*id,sign[14];
chara[14];
FILE*fp1,*fp2,*fp3;
voiderror(intn){
switch(n){
case1:
printf("常数说明中的\"=\"写成了\":
=\"。
\n");
break;
case2:
printf("常数说明中\"=\"后应是数字。
\n");
break;
case3:
printf("常数说明中的标识符后应是\"=\"。
\n");
break;
case4:
printf("program,const,var,procedure后应为标识符。
\n");
break;
case5:
printf("漏掉了\",\"或\";\"。
\n");
break;
case6:
printf("过程说明的符号不正确。
\n");
break;
case7:
printf("应该是语句的开始符。
\n");
break;
case8:
printf("程序体内语句部分的后跟符不正确。
\n");
break;
case9:
printf("程序的结尾丢了句号\".\"。
\n");
break;
case10:
printf("语句之间漏了\";\"。
\n");
break;
case11:
printf("标识符未说明。
\n");
break;
case12:
printf("赋值语句中,赋值号左部标识符属性应是变量。
\n");
break;
case13:
printf("赋值语句左部标识符后应是赋值号\":
=\"。
\n");
break;
case14:
printf("call后应为标识符。
\n");
break;
case15:
printf("call后标识符属性应为过程。
\n");
break;
case16:
printf("条件语句中丢了\"then\"。
\n");
break;
case17:
printf("丢了\"end\"或\";\"。
\n");
break;
case18:
printf("while型循环语句中丢了\"do\"。
\n");
break;
case19:
printf("语句后的符号不正确。
\n");
break;
case20:
printf("应为关系运算符。
\n");
break;
case21:
printf("表达式内标识符属性不能是过程。
\n");
break;
case22:
printf("表达式中漏掉右括号\")\"。
\n");
break;
case23:
printf("因子后的非法符号。
\n");
break;
case24:
printf("表达式的开始符不能是此符号。
\n");
break;
case25:
printf("不能识别的符号。
\n");
break;
case26:
printf("程序的层次越界。
\n");
break;
case27:
printf("程序应该以program保留字开始。
\n");
break;
case28:
printf("程序没有程序主体。
\n");
break;
case31:
printf("数越界。
\n");
break;
case32:
printf("read语句括号中的标识符不是变量。
\n");
break;
case33:
printf("read/write单词后应为左括号。
\n");
break;
case34:
printf("read/write语句括号中的标识符应是申明过的变量。
\n");
break;
case35:
printf("read/write语句没有右括号。
\n");
}
}
voidgetsym(){
inti,n=1,l=0;
intj,m;
do{
while(ch==''||ch==10||ch==9){
if(ch==10)
n++;
ch=fgetc(fp1);
}
if(ch>='a'&&ch<='z'){//名字或保留字以字母开头
k=0;
do{
if(k<10){
a[k]=ch;
k+=1;
}
ch=fgetc(fp1);
}while(ch>='a'&&ch<='z'||ch>='0'&&ch<='9');//读取一串字符
a[k]='\0';//字符串最后置结束符
id=a;//单词自身值赋给id
for(i=0;i<14;i++){
for(j=0;j if(a[j]==word[i][j])//搜索当前字符是否为保留字 continue; else break; } if(j==k&&word[i][j]=='\0'){ sym=wsym[i]; break; } if(j==k&&word[i][j]! ='\0'){ sym=ident; break; } } if(i>13) sym=ident;//将字符串类别值赋给sym } elseif(ch>='0'&&ch<='9'){//检测是否为数字: 以0..9开头 k=0; num=0; sym=number; do{ a[k]=ch; num=10*num+(ch-'0'); k+=1; ch=fgetc(fp1); }while(ch>='0'&&ch<='9');//读取数字,并转换为数 k--; id=a; if(k>14){ num=0; error(31);//数字位数超过14位出错 printf("第%d行出错\n",n); k=0; *(id+k)='0'; a[k]='0'; } } elseif(ch==': '){//检测赋值符号 k=0; ch=fgetc(fp1); *(id+k)=': '; a[k]=': '; if(ch=='='){ sym=becomes; k=k+1; *(id+k)='='; a[k]='='; ch=fgetc(fp1); } else{ error(25); sym=nul;//不能识别的符号 printf("第%d行出错\n",n); } } elseif(ch=='<'){//检测小于或小于等于符号 k=0; ch=fgetc(fp1); *(id+k)='<'; a[k]='<'; if(ch=='='){ sym=leq; k+=1; *(id+k)='='; a[k]='='; ch=fgetc(fp1); } else sym=lss; } elseif(ch=='>'){//检测大于或大于等于符号 k=0; ch=fgetc(fp1); *(id+k)='>'; a[k]='>'; if(ch=='='){ sym=geq; k+=1; *(id+k)='='; a[k]='='; ch=fgetc(fp1); } else sym=gtr; } elseif(ch=='+'||ch=='-'||ch=='*'||ch=='/'||ch=='('||ch==')'||ch==','||ch=='.'||ch=='#'||ch==';'||ch=='='){//单字符符号处理 sym=ssym[ch]; k=0; a[k]=ch; id=a; ch=fgetc(fp1); } else{//当符号不能满足上述条件时,全部按不能识别的符号处理 sym=nul; k=0; a[k]=ch; id=a; error(25); printf("第%d行出错\n",n); ch=fgetc(fp1); } switch(sym){ casenul: str="nul";break; caseident: str="ident";break; casenumber: str="number";break; caseplus: str="plus";break; caseminus: str="minus";break; casetimes: str="times";break; caseslash: str="slash";break; caseoddsym: str="oddsym";break; caseeql: str="eql";break; caseneq: str="neq";break; caselss: str="lss";break; caseleq: str="leq";break; casegtr: str="gtr";break; casegeq: str="geq";break; caselparen: str="lparen";break; caserparen: str="rparen";break; casecomma: str="comma";break; casesemicolon: str="semicolon";break; caseperiod: str="period";break; casebecomes: str="becomes";break; casebeginsym: str="beginsym";break; caseendsym: str="endsym";break; caseifsym: str="ifsym";break; casethensym: str="thensym";break; casewhilesym: str="whilesym";break; casewritesym: str="writesym";break; casereadsym: str="readsym";break; casedosym: str="dosym";break; casecallsym: str="callsym";break; caseconstsym: str="constsym";break; casevarsym: str="varsym";break; caseprocsym: str="procsym";break; caseprogsym: str="progsym";break; } printf("("); for(m=0;m<=k;m++) printf("%c",*(id+m)); *(id+k+1)='\0'; printf("\t"); printf("%s)",str); printf("\n"); fprintf(fp2,"(%s%s)",id,str); fprintf(fp2,"\n"); l++; }while(sym==nul&&l<10); } voidenter(enumobjectk,int*ptx,intlev,int*pdx) { //mm=(int*)malloc(sizeof(int)); intmmm; (*ptx)++; *table[(*ptx)].name=*sign; table[(*ptx)].kind=k; switch(k){ caseconstant: table[(*ptx)].val=num; break; casevariable: table[(*ptx)].level=lev; table[(*ptx)].adr=(*pdx); (*pdx)++; break; caseprocedure: table[(*ptx)].level=lev; break; } mmm=*ptx; //printf("11111111%d2222222\n",mmm); *mm=mmm; } intposition(char*idt,inttx){ inti,j,m; for(j=0;j table[0].name[j]=*(idt+j); for(i=tx;i>0;i--){ for(m=0;m if(table[i].name[m]! =*(idt+m)) break; else continue; } if(m==k+1&&table[i].name[m]=='\0'){ returni; break; } else continue; } if(i==0) return0; } /*常量声明处理*/ intconstdeclaration(int*ptx,intlev,int*pdx){ if(sym==ident){ *sign=*a; getsym(); if(sym==eql||sym==becomes){ if(sym==becomes) error (1); getsym(); if(sym==number) { enter(constant,ptx,lev,pdx); } else error (2); } else error(3); } else error(4); getsym(); return0; } /*变量声明处理*/ intvardeclaration(int*ptx,intlev,int*pdx){ if(sym==ident){ *sign=*a; enter(variable,ptx,lev,pdx); getsym(); } else error(4); return0; } //因子处理 intfactor(int*ptx,intlev){//******************************************************************factor************* inti; while(sym==ident||sym==number||sym==lparen)/*循环直到不是因子开始符号*/ { if(sym==ident)/*因子为常量或变量*/ { i=position(id,*ptx);/*查找名字*/ if(i==0) error(11);/*标示符未声明*/ getsym(); } elseif(sym==number)/*因子为数*/ { if(num>2047)/*数字越界*/ { error(31); num=0; } getsym(); } else/*因子为表达式*/ { getsym(); expression(ptx,lev); if(sym==rparen) getsym(); else error(22);/*缺少右括号*/ } } return0; }//***********************************************************factor********************* //项处理 intterm(int*ptx,intlev)//**************************************************************term******************* { //enumsymbolmulop;/*用于保存乘除法符号,定义为全局变量*/ factor(ptx,lev);/*处理因子*/ while(sym==times||sym==slash) { getsym(); factor(ptx,lev); } return0; }//*************************************************************term********************* /*表达式处理*/ intexpression(int*ptx,intlev)//***********************************************************expression********************* { enumsymboladdop;/*用于保存正负号*/ if(sym==plus||sym==minus)/*开头的正负号,此时当前表达式被看做一个正或负的项*/ { addop=sym;//保存开头的正负号 getsym(); term(ptx,lev); } else term(ptx,lev);//处理项 while(sym==plus||sym==minus) { getsym(); term(ptx,lev);//处理项 } return0; }//****************************************************************expression**************** //条件语句处理 intcondition(int*ptx,intlev){ enumsymbolrelop; if(sym==oddsym){ getsym(); expression(ptx,lev); } else{ expression(ptx,lev); if(sym! =eql&&sym! =neq&&sym! =lss&&sym! =leq&&sym! =gtr&&sym! =geq) error(20); else{ relop=sym; getsym(); expression(ptx,lev); } } return0; } //语句处理 intstatement(int*ptx,intlev){ inti; if(sym==ident){ i=position(id,*ptx); if(i==0) error(11); else{ if(table[i].kind! =variable){ error(12); i=0; } else{ getsym(); if(sym==becomes) getsym(); else error(13); expression(ptx,lev); printf("赋值语句\n"); fprintf(fp2,"赋值语句\n"); } } } elseif(sym==readsym){ getsym(); if(sym! =lparen) error(33); else{ do{ getsym(); if(sym==ident)
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- PL0 源程序 编译 原理 实验 代码