PL0源程序编译原理实验代码.docx
《PL0源程序编译原理实验代码.docx》由会员分享,可在线阅读,更多相关《PL0源程序编译原理实验代码.docx(26页珍藏版)》请在冰豆网上搜索。
![PL0源程序编译原理实验代码.docx](https://file1.bdocx.com/fileroot1/2022-11/30/a4acd14c-82d6-4f97-a9df-29449e037b76/a4acd14c-82d6-4f97-a9df-29449e037b761.gif)
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;jif(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;jtable[0].name[j]=*(idt+j);
for(i=tx;i>0;i--){
for(m=0;mif(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)