小型编译程序高级语言到四元式的编译.docx
《小型编译程序高级语言到四元式的编译.docx》由会员分享,可在线阅读,更多相关《小型编译程序高级语言到四元式的编译.docx(38页珍藏版)》请在冰点文库上搜索。
![小型编译程序高级语言到四元式的编译.docx](https://file1.bingdoc.com/fileroot1/2023-4/30/8c15c02f-9038-4031-8053-aa4f9663a54b/8c15c02f-9038-4031-8053-aa4f9663a54b1.gif)
小型编译程序高级语言到四元式的编译
小型编译程序:
高级语言到四元式的编译
#include"stdio.h"/*如果使用TC的话,需要配置头文件路径*/
#include"string.h"
#defineACC-2
/************************/
#definesy_if0
#definesy_then1
#definesy_else2
#definesy_while3
#definesy_begin4
#definesy_do5
#definesy_end6
#definea7
#definesemicolon8
#definee9
#definejinghao10
#defineS11
#defineL12
#definetempsy15
#defineEA18/*Eand*/
#defineE019/Eor*/
#defineplus34
#definetimes36
#definebecomes38
#defineop_and39
#defineop_or40
#defineop_not41
#definerop42
#definelparent48
#definerparent49
#defineident56
#defineintconst57
/*********************************/
charch='\0';/*从字符缓冲区读取当前字符*/
intcount=0;/*词法分析结果缓冲区计数器*/
staticcharspelling[10]={""};/*存放识别的字*/
staticcharline[81]={""};/*一行字符缓冲区,最多80个字符*/
char*pline;/*字符缓冲区指针*/
staticcharntab1[100][10];/*变量名表,共100项,每项长度10*/
structntab
{
inttc;/*真值*/
intfc;/*假值*/
}ntab2[200];/*在布尔表达式E中保存有关布尔变量的真、假值*/
intlabel=0;/*指向ntab2的指针*/
structrwords{/*存放临时变量的表的定义*/
charsp[10];
intsy;
};
/*(保留字表)匹配表的结构,用来与输入缓冲区中的单词进行匹配*/
/*匹配表初始化,大小为10*/
structrwordsreswords[10]={{"if",sy_if},
{"do",sy_do},
{"else",sy_else},
{"while",sy_while},
{"then",sy_then},
{"begin",sy_begin},
{"end",sy_end},
{"and",op_and},
{"or",op_or},
{"not",op_not}};
structaa{
intsy1;/*存放名字*/
intpos;/*存放名字所对应的地址*/
}buf[1000],/*词法分析结果缓冲区*/
n,/*读取二元式的当前字符*/
n1,/*当前表达式中的字符*/
E,/*非终结符*/
sstack[100],/*算术或布尔表达式加工处理使用的符号栈*/
ibuf[100],/*算术或布尔表达式使用的缓冲区*/
stack[1000];/*语法分析加工处理使用的符号栈*/
structaaoth;/*四元式中空白位置*/
structfourexp{
charop[10];
structaaarg1;
structaaarg2;
intresult;
}fexp[200];/*四元式的结构定义*/
intssp=0;/*指向sstack栈指针*/
structaa*pbuf=buf;/*指向词法分析缓冲区的指针*/
intnlength=0;/*词法分析中记录单词的长度*/
intlnum=0;/*源程序行数记数,源程序长度*/
inttt1=0;/*变量名表指针*/
FILE*cfile;/*源程序文件,~为结束符*/
/*FILE*mfile;*/
intnewt=0;/*临时变量计数器*/
intnxq=100;/*nxq指向下一个形成的四元式的地址*/
/*每次执行gen()时,地址自动增1*/
intlr;/*扫描LR分析表1过程中保存的当前状态值*/
intlr1;/*扫描LR分析表2或表3所保存的当前状态值*/
intsp=0;/*查找LR分析表时状态栈的栈顶指针*/
intstack1[100];/*状态栈1的定义*/
intsp1=0;/*状态栈1的栈顶指针*/
intnum=0;/*算术或布尔表达式缓冲区指针*/
structll{
intnxq1;/*记录下一条四元式的地址*/
inttc1;/*真值链*/
intfc1;/*假值链*/
}labelmark[10];/*记录语句嵌套层次的数组,*/
/*即记录嵌套中每层的布尔表达式E的首地址*/
intlabeltemp[10];/*记录语句嵌套层次的数组,*/
/*即记录每层else之前的四元式地址*/
intpointmark=-1,/*labelmark数组指针*/
pointtemp=-1;/*labeltemp数组指针*/
intsign=0;/*sign=1,为赋值语句;sign=2,为布尔表达式。
*/
/**************程序语句LR分析表*********************/
staticintaction[19][13]=
/*0*/{{2,-1,-1,3,4,-1,-1,5,-1,-1,-1,-1,-1},
/*1*/{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,ACC,-1,-1},
/*2*/{-1,-1,-1,-1,-1,-1,-1,-1,-1,6,-1,-1,-1},
/*3*/{-1,-1,-1,-1,-1,-1,-1,-1,-1,7,-1,-1,-1},
/*4*/{2,-1,-1,3,4,-1,-1,5,-1,-1,-1,9,8},
/*5*/{-1,-1,104,-1,-1,-1,104,-1,104,-1,104,-1,-1,},
/*6*/{-1,10,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
/*7*/{-1,-1,-1,-1,-1,11,-1,-1,-1,-1,-1,-1,-1},
/*8*/{-1,-1,-1,-1,-1,-1,12,-1,-1,-1,-1,-1,-1},
/*9*/{-1,-1,-1,-1,-1,-1,105,-1,13,-1,-1,-1,-1},
/*10*/{2,-1,-1,3,4,-1,-1,5,-1,-1,-1,14,-1},
/*11*/{2,-1,-1,3,4,-1,-1,5,-1,-1,-1,15,-1},
/*12*/{-1,-1,103,-1,-1,-1,103,-1,103,-1,103,-1,-1},
/*13*/{2,-1,-1,3,4,-1,-1,5,-1,-1,-1,9,16},
/*14*/{-1,-1,17,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
/*15*/{-1,-1,102,-1,-1,-1,102,-1,102,-1,102,-1,-1},
/*16*/{-1,-1,-1,-1,-1,-1,106,-1,-1,-1,-1,-1,-1},
/*17*/{2,-1,-1,3,4,-1,-1,5,-1,-1,-1,18,-1},
/*18*/{-1,-1,101,-1,-1,-1,101,-1,101,-1,101,-1,-1}};
/**************算术表示式的LR分析表************************/
staticintaction1[10][7]=
/*0*/{{3,-1,-1,2,-1,-1,1},
/*1*/{-1,4,5,-1,-1,ACC,-1},
/*2*/{3,-1,-1,2,-1,-1,6},
/*3*/{-1,104,104,-1,104,104,-1},
/*4*/{3,-1,-1,2,-1,-1,7},
/*5*/{3,-1,-1,2,-1,-1,8},
/*6*/{-1,4,5,-1,9,-1,-1},
/*7*/{-1,101,5,-1,101,101,-1},
/*8*/{-1,102,102,-1,102,102,-1},
/*9*/{-1,103,103,-1,103,103,-1}};
/*************布尔表示式的LR分析表********************/
staticintaction2[16][11]=
/*0*/{{1,-1,4,-1,5,-1,-1,-1,13,7,8},
/*1*/{-1,2,-1,101,-1,101,101,101,-1,-1,-1},
/*2*/{3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
/*3*/{-1,-1,-1,102,-1,102,102,102,-1,-1,-1},
/*4*/{1,-1,4,-1,5,-1,-1,-1,11,7,8},
/*5*/{1,-1,4,-1,5,-1,-1,-1,6,7,8},
/*6*/{-1,-1,-1,104,-1,9,10,104,-1,-1,-1},
/*7*/{1,-1,4,-1,5,-1,-1,-1,14,7,8},
/*8*/{1,-1,4,-1,5,-1,-1,-1,15,7,8},
/*9*/{105,-1,105,-1,105,-1,-1,-1,-1,-1,-1},
/*10*/{107,-1,107,-1,107,-1,-1,-1,-1,-1,-1},
/*11*/{-1,-1,-1,12,-1,9,10,-1,-1,-1,-1},
/*12*/{-1,-1,-1,103,-1,103,103,103,-1,-1,-1},
/*13*/{-1,-1,-1,-1,-1,9,10,ACC,-1,-1,-1},
/*14*/{-1,-1,-1,106,-1,9,10,106,-1,-1,-1},
/*15*/{-1,-1,-1,108,-1,9,10,108,-1,-1,-1}};
/*************从文件读一行到缓冲区*************/
voidreadline()
{
charch1;
pline=line;
ch1=fgetc(cfile);
while(ch1!
='\n')
{
*pline=ch1;
pline++;
ch1=fgetc(cfile);
}
*pline='\0';
pline=line;
}
/*************从缓冲区读取一个字符*********************/
voidreadch()
{
if(ch=='\0')
{
readline();
lnum++;
}
ch=*pline;
pline++;
}
/***************标识符和关键字的识别******************/
find(charspel[])
{
intss1=0;
intii=0;
while((ss1==0)&&(ii{
if(!
strcmp(spel,ntab1[ii]))ss1=1;
ii++;
}
if(ss1==1)returnii-1;
elsereturn-1;
}
voididentifier()
{
intiii=0,j,k;
intss=0;
k=0;
do
{
spelling[k]=ch;
k++;
readch();
}while(((ch>='a')&&(ch<='z'))||((ch>='0')&&(ch<='9')));
pline--;
spelling[k]='\0';
while((ss==0)&&(iii<10))
{
if(!
strcmp(spelling,reswords[iii].sp))ss=1;
iii++;
}
/*关键字匹配*/
if(ss==1)
{
buf[count].sy1=reswords[iii-1].sy;
}
else
{
buf[count].sy1=ident;
j=find(spelling);
if(j==-1)
{
buf[count].pos=tt1;
strcpy(ntab1[tt1],spelling);
tt1++;
nlength++;
}
elsebuf[count].pos=j;
}
count++;
for(k=0;k<10;k++)spelling[k]='';
}
/***********************数字的识别**********************/
voidnumber()
{
intivalue=0;
intdigit;
do
{
digit=ch-'0';
ivalue=ivalue*10+digit;
readch();
}while((ch>='0')&&(ch<='9'));
buf[count].sy1=intconst;
buf[count].pos=ivalue;
count++;
pline--;
}
/******************扫描主函数**************************/
voidscan()
{
while(ch!
='~')
{
switch(ch)
{
case'':
break;
case'a':
case'b':
case'c':
case'd':
case'e':
case'f':
case'g':
case'h':
case'i':
case'j':
case'k':
case'l':
case'm':
case'n':
case'o':
case'p':
case'q':
case'r':
case's':
case't':
case'u':
case'v':
case'w':
case'x':
case'y':
case'z':
identifier();
break;
case'0':
case'1':
case'2':
case'3':
case'4':
case'5':
case'6':
case'7':
case'8':
case'9':
number();
break;
case'<':
readch();
if(ch=='=')
{
buf[count].pos=0;
}
else
{
if(ch=='>')buf[count].pos=4;
else
{
buf[count].pos=1;
pline--;
}
}
buf[count].sy1=rop;
count++;
break;
case'>':
readch();
if(ch=='=')
{
buf[count].pos=2;
}
else
{
buf[count].pos=3;
pline--;
}
buf[count].sy1=rop;
count++;
break;
case'(':
buf[count].sy1=lparent;
count++;
break;
case')':
buf[count].sy1=rparent;
count++;
break;
case'#':
buf[count].sy1=jinghao;
count++;
break;
case'+':
buf[count].sy1=plus;
count++;
break;
case'*':
buf[count].sy1=times;
count++;
break;
case':
':
readch();
if(ch=='=')
buf[count].sy1=becomes;
count++;
break;
case'=':
buf[count].sy1=rop;
buf[count].pos=5;
count++;
break;
case';':
buf[count].sy1=semicolon;
count++;
break;
}
readch();
}
buf[count].sy1=-1;
}
/********************************************************************/
voidreadnu()
{
if(pbuf->sy1>=0)
{
n.sy1=pbuf->sy1;
n.pos=pbuf->pos;
pbuf++;
}
}
/****************中间变量的生成************************/
newtemp()
{
newt++;
returnnewt;
}
/*********************生成四元式*************************/
gen(charop1[],structaaarg11,structaaarg22,intresult1)
{
strcpy(fexp[nxq].op,op1);
fexp[nxq].arg1.sy1=arg11.sy1;
fexp[nxq].arg1.pos=arg11.pos;
fexp[nxq].arg2.sy1=arg22.sy1;
fexp[nxq].arg2.pos=arg22.pos;
fexp[nxq].result=result1;
nxq++;
returnnxq-1;
}
/***************布尔表示式的匹配****************/
merg(intp1,intp2)
{
intp;
if(p2==0)returnp1;
else
{
p=p2;
while(fexp[p].result!
=0)p=fexp[p].result;
fexp[p].result=p1;
returnp2;
}
}
voidbackpatch(intp,intt)
{
inttempq;
intq;
q=p;
while(q!
=0)
{
tempq=fexp[q].result;
fexp[q].result=t;
q=tempq;
}
}
/****************************************************/
change1(intchan)
{
switch(chan)
{
caseident:
caseintconst:
return0;
caseplus:
return1;
casetimes:
return2;
caselparent:
return3;
caserparent:
return4;
casejinghao:
return5;
casetempsy:
return6;
default:
return100;
}
}
change2(intchan)
{
switch(chan)
{
caseident:
caseintconst:
return0;
caserop:
return1;
caselparent:
return2;
caserparent:
return3;
caseop_not:
return4;
caseop_and:
return5;
caseop_or:
return6;
casejinghao:
return7;
casetempsy:
return8;
caseEA:
return9;
caseE0:
return10;
default:
return100;
}
}
/*******************赋值语句的分析*********************/
voidlrparse1(intnum)
{intlr1;
lr1=action1[stack1[sp1]][change1(n1.sy1)];
if(lr1==-1)
{
printf("\n算术表达式或赋值语句出错!
\n");
getchar();
//exit(0);
}
if((lr1<10)&&(lr1>=0))
{
sp1++;
stack1[sp1]=lr1;
if(n1.sy1!
=tempsy)
{
ssp++;
num++;
sstack[ssp].s