📄 analyzer.c
字号:
/**************************************************************
程序名称:词法与语法分析器(Analyzer for compiler)
作者:李建华 计算机002班
功能:完成对一种类Pascal语言的词法分析与语法分析
**************************************************************/
#include "stdio.h"
#include "string.h"
#include "init.h"
/*从文件读一行到缓冲区*/
readline()
{
char tempch;
pline=line;
tempch=getc(cfile);
while(tempch!='\n')
{
*pline=tempch;
pline++;
tempch=getc(cfile);
}
*pline='\0';
pline=line;
}
/*从缓冲区中读取一个字符*/
readch()
{
if(ch=='\0')
{
readline();
programlinenum++;
}
ch=*pline;
pline++;
}
/*标识符和关键字的识别*/
find(char spel[])
{
int ss=0;
int ii=0;
while((ss==0)&&(ii<nlength))
{
if(!strcmp(spel,ntab1[ii]))ss=1;
ii++;
}
if(ss==1)return ii-1;
else return -1;
}
void identifier()
{
int tempi=0,j,k=0;
int ss=0;
do
{
spelling[k]=ch;
k++;
readch();
}while(((ch>='a')&&(ch<='z'))||((ch>='0')&&(ch<='9')));
pline--;
spelling[k]='\0';
while((ss==0)&&(tempi<10))
{
if(!strcmp(spelling,reswords[tempi].sp)) ss=1;
tempi++;
}
/*关键字匹配*/
if(ss==1)
{
buf[count].sy1=reswords[tempi-1].sy;
}
else
{
buf[count].sy1=IVAR;
j=find(spelling);
if(j==-1)
{
buf[count].pos=tt1;
strcpy(ntab1[tt1],spelling);
tt1++;
nlength++;
}
else buf[count].pos=j;
}
count++;
for(k=0;k<10;k++)spelling[k]=' ';
}
/*数字识别*/
number()
{
int temp=0;
int digit;
do
{
digit=ch-'0';
temp=temp*10+digit;
readch();
}while((ch>='0')&&(ch<='9'));
buf[count].sy1=INTCONST;
buf[count].pos=temp;
count++;
pline--;
}
/*扫描主函数*/
scan()
{
int i;
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=WELL;
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;
}
/***********************************************************************************/
readnu()
{
if(pbuf->sy1>=0)
{
n.sy1=pbuf->sy1;
n.pos=pbuf->pos;
pbuf++;
}
}
/*中间变量的生成*/
newtemp()
{
newt++;
return newt;
}
/*生成四元式*/
gen(char op1[],struct aa arg11,struct aa arg22,int result1)
{
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++;
return nxq-1;
}
/*布尔表达式的匹配*/
merg(int p1,int p2)
{
int p;
if(p2==0)return p1;
else
{
p=p2;
while(fexp[p].result!=0) p=fexp[p].result;
fexp[p].result=p1;
return p2;
}
}
/*回填函数*/
backpatch(int p,int t)
{
int tempq;
int q;
q=p;
while(q!=0)
{
tempq=fexp[q].result;
fexp[q].result=t;
q=tempq;
}
}
/****************************************************************************************/
change1(int chan)
{
switch(chan)
{
case IVAR:
case INTCONST:
return 0;
case PLUS:
return 1;
case TIMES:
return 2;
case LPARENT:
return 3;
case RPARENT:
return 4;
case WELL:
return 5;
case TEMPVAR:
return 6;
}
}
change2(int chan)
{
switch(chan)
{
case IVAR:
case INTCONST:
return 0;
case ROP:
return 1;
case LPARENT:
return 2;
case RPARENT:
return 3;
case OPTION_NOT:
return 4;
case OPTION_AND:
return 5;
case OPTION_OR:
return 6;
case WELL:
return 7;
case TEMPVAR:
return 8;
case EA:
return 9;
case EO:
return 10;
}
}
/*赋值语句的分析*/
lrparse1(int num)
{
lr1=action1[stack1[sp1]][change1(n1.sy1)];
if(lr1==-1)
{
printf("算术表达式或赋值语句出错!\n");
getch();
exit(0);
}
if((lr1<10)&&(lr1>=0)) /* 移进 */
{
sp1++;
stack1[sp1]=lr1;
if(n1.sy1!=TEMPVAR)
{
ssp++;
num++;
sstack[ssp].sy1=n1.sy1;
sstack[ssp].pos=n1.pos;
}
n1.sy1=ibuf[num].sy1;
n1.pos=ibuf[num].pos;
lrparse1(num);
}
if((lr1>=100)&&(lr1<105)) /* 归约 */
{
switch(lr1)
{
case 100: /* S'->E */
break;
case 101: /* E->E+E */
E.pos=newtemp();
gen("+",sstack[ssp-2],sstack[ssp],E.pos+100);
ssp=ssp-2;
sstack[ssp].sy1=TEMPVAR;
sstack[ssp].pos=E.pos;
sp1=sp1-3;
break;
case 102: /* E->E*E */
E.pos=newtemp();
gen("*",sstack[ssp-2],sstack[ssp],E.pos+100);
ssp=ssp-2;
sstack[ssp].sy1=TEMPVAR;
sstack[ssp].pos=E.pos;
sp1=sp1-3;
break;
case 103: /* E->(E) */
E.pos=sstack[ssp-1].pos;
ssp=ssp-2;
sstack[ssp].sy1=TEMPVAR;
sstack[ssp].pos=E.pos;
sp1=sp1-3;
break;
case 104: /* E->i */
E.pos=sstack[ssp].pos;
sp1--;
break;
}
n1.sy1=TEMPVAR;
n1.pos=E.pos;
lrparse1(num);
}
if((lr1==ACC)&&(stack1[sp1]==1))/* 归约A->i:=E */
{
gen(":=",sstack[ssp],oth,ibuf[0].pos);
ssp=ssp-3;
sp1=sp1-3;
}
}
/*布尔表达式分析*/
lrparse2(int num)
{
int templabel;
lr1=action2[stack1[sp1]][change2(n1.sy1)];
if(lr1==-1)
{
if(sign==2) printf("\nwhile语句出错!\n");
if(sign==3) printf("\nif语句出错!\n");
getch();
exit(0);
}
if((lr1<16)&&(lr1>=0))/* 移进 */
{
sp1++;
stack1[sp1]=lr1;
ssp++;
sstack[ssp].sy1=n1.sy1;
sstack[ssp].pos=n1.pos;
if((n1.sy1!=TEMPVAR)&&(n1.sy1!=EA)&&(n1.sy1!=EO)) num++;
n1.sy1=ibuf[num].sy1;
n1.pos=ibuf[num].pos;
lrparse2(num);
}
if((lr1>=100)&&(lr1<109))/* 归约 */
{
switch(lr1)
{
case 100:/* S'->B */
break;
case 101:/* B->i */
ntab2[label].tc=nxq;
ntab2[label].fc=nxq+1;
gen("jnz",sstack[ssp],oth,0);
gen("j",oth,oth,0);
sp1--;
ssp--;
label++;
n1.sy1=TEMPVAR;
break;
case 102:/* B->i ROP i */
ntab2[label].tc=nxq;
ntab2[label].fc=nxq+1;
switch(sstack[ssp-1].pos)
{
case 0:
gen("j<=",sstack[ssp-2],sstack[ssp],0);
break;
case 1:
gen("j<",sstack[ssp-2],sstack[ssp],0);
break;
case 2:
gen("j>=",sstack[ssp-2],sstack[ssp],0);
break;
case 3:
gen("j>",sstack[ssp-2],sstack[ssp],0);
break;
case 4:
gen("j<>",sstack[ssp-2],sstack[ssp],0);
break;
case 5:
gen("j=",sstack[ssp-2],sstack[ssp],0);
break;
}
gen("j",oth,oth,0);
ssp=ssp-3;
sp1=sp1-3;
label++;
n1.sy1=TEMPVAR;
break;
case 103:/* B->(B) */
label=label-1;
ssp=ssp-3;
sp1=sp1-3;
label++;
n1.sy1=TEMPVAR;
break;
case 104:/* B->not B */
label=label-1;
templabel=ntab2[label].tc;
ntab2[label].tc=ntab2[label].fc;
ntab2[label].fc=templabel;
ssp=ssp-2;
sp1=sp1-2;
label++;
n1.sy1=TEMPVAR;
break;
case 105:/* A->Band */
backpatch(ntab2[label-1].tc,nxq);
label=label-1;
ssp=ssp-2;
sp1=sp1-2;
label++;
n1.sy1=EA;
break;
case 106:/* B->AB */
label=label-2;
ntab2[label].tc=ntab2[label+1].tc;
ntab2[label].fc=merg(ntab2[label].fc,ntab2[label+1].fc);
ssp=ssp-2;
sp1=sp1-2;
label++;
n1.sy1=TEMPVAR;
break;
case 107:/* 0->B or */
backpatch(ntab2[label-1].fc,nxq);
label=label-1;
ssp=ssp-2;
sp1=sp1-2;
label++;
n1.sy1=EO;
break;
case 108:/* B->0B */
label=label-2;
ntab2[label].fc=ntab2[label+1].fc;
ntab2[label].tc=merg(ntab2[label].tc,ntab2[label+1].tc);
ssp=ssp-2;
sp1=sp1-2;
label++;
n1.sy1=TEMPVAR;
break;
}
lrparse2(num);
}
if(lr1==ACC)return 1;
}
/*测试字符是否为表达式中的值(不包括“;”)*/
test(int value)
{
switch(value)
{
case INTCONST:
case IVAR:
case PLUS:
case TIMES:
case BECOMES:
case LPARENT:
case RPARENT:
case ROP:
case OPTION_AND:
case OPTION_OR:
case OPTION_NOT:
return 1;
default:
return 0;
}
}
/*程序语句处理*/
lrparse()
{
int i1=0;
int num=0;
/* 指向表达式缓冲区 */
if(test(n.sy1))
{
if(stack[sp].sy1==SYMBOL_WHILE)sign=2;
else
{
if(stack[sp].sy1==SYMBOL_IF)sign=3;
else sign=1;
}
do
{
ibuf[i1].sy1=n.sy1;
ibuf[i1].pos=n.pos;
readnu();
i1++;
}while(test(n.sy1));
ibuf[i1].sy1=WELL;
pbuf--;
sstack[0].sy1=WELL;
ssp=0;
if(sign==1)/*赋值语句处理*/
{
sp1=0;
stack1[sp1]=0;
num=2;
n1.sy1=ibuf[num].sy1;
n1.pos=ibuf[num].pos;
lrparse1(num);
n.sy1=a;
}
if((sign==2)||(sign==3))/*布尔表达式处理*/
{
pointmark++;
labelmark[pointmark].nxq1=nxq;
sp1=0;
stack1[sp1]=0;
num=0;
n1.sy1=ibuf[num].sy1;
n1.pos=ibuf[num].pos;
lrparse2(num);
labelmark[pointmark].tc1=ntab2[label-1].tc;
labelmark[pointmark].fc1=ntab2[label-1].fc;
backpatch(labelmark[pointmark].tc1,nxq);
n.sy1=e;
}
}
lr=action[stack[sp].pos][n.sy1];
printf("stack[%d]=%d\t\tn=%d\t\tlr=%d\n",sp,stack[sp].pos,n.sy1,lr);
if((lr<19)&&(lr>=0))/* 移进 */
{
sp++;
stack[sp].pos=lr;
stack[sp].sy1=n.sy1;
readnu();
lrparse();
}
if((lr<=106)&&(lr>=100))/* 归约 */
{
switch(lr)
{
case 100:/* S'->S */
break;
case 101:/* S->if e then S else S */
printf("S->if e then S else S 归约\n");
sp=sp-6;
n.sy1=S;
fexp[labeltemp[pointtemp]].result=nxq;
pointtemp--;
if(stack[sp].sy1==SYMBOL_THEN)
{
gen("j",oth,oth,0);
backpatch(labelmark[pointmark].fc1,nxq);
pointtemp++;
labeltemp[pointtemp]=nxq-1;
}
pointmark--;
if(stack[sp].sy1==SYMBOL_DO)
{
gen("j",oth,oth,labelmark[pointmark].nxq1);
backpatch(labelmark[pointmark].fc1,nxq);
}
break;
case 102:/* S->while e do S */
printf("S->while e do S 归约\n");
sp=sp-4;
n.sy1=S;
pointmark--;
if(stack[sp].sy1==SYMBOL_DO)
{
gen("j",oth,oth,labelmark[pointmark].nxq1);
backpatch(labelmark[pointmark].fc1,nxq);
}
if(stack[sp].sy1==SYMBOL_THEN)
{
gen("j",oth,oth,0);
fexp[labelmark[pointmark].fc1].result=nxq;
pointtemp++;
labeltemp[pointtemp]=nxq-1;
}
break;
case 103:/* S->begin L end */
printf("S->begin L end 归约\n");
sp=sp-3;
n.sy1=S;
if(stack[sp].sy1==SYMBOL_THEN)
{
gen("j",oth,oth,0);
backpatch(labelmark[pointmark].fc1,nxq);
pointtemp++;
labeltemp[pointtemp]=nxq-1;
}
if(stack[sp].sy1==SYMBOL_DO)
{
gen("j",oth,oth,labelmark[pointmark].nxq1);
backpatch(labelmark[pointmark].fc1,nxq);
}
getch();
break;
case 104:/* S->a */
printf("S->a 归约\n");
sp=sp-1;
n.sy1=S;
if(stack[sp].sy1==SYMBOL_THEN)
{
gen("j",oth,oth,0);
backpatch(labelmark[pointmark].fc1,nxq);
pointtemp++;
labeltemp[pointtemp]=nxq-1;
}
if(stack[sp].sy1==SYMBOL_DO)
{
gen("j",oth,oth,labelmark[pointmark].nxq1);
backpatch(labelmark[pointmark].fc1,nxq);
}
break;
case 105:/* L->S */
printf("L->S 归约\n");
sp=sp-1;
n.sy1=L;
break;
case 106:/* L->S;L */
printf("L->S;L 归约\n");
sp=sp-3;
n.sy1=L;
break;
}
getch();
pbuf--;
lrparse();
}
if(lr==ACC) return ACC;
}
/*显示词法分析结果*/
void showworda()
{
int temp=0;
printf("\n====================词法分析结果====================\n");
for(temp=0;temp<=count;temp++)
{
printf("%d\t%d\n",buf[temp].sy1,buf[temp].pos);
if(temp==20)
{
printf("按任意键继续......\n");
getch();
}
}
getch();
}
/*显示四元式分析结果*/
void show4result()
{
int temp=100;
printf("\n====================四元式分析结果====================\n");
for(temp=100;temp<nxq;temp++)
{
printf("%d\t",temp);
printf("(%s\t,",fexp[temp].op);
if(fexp[temp].arg1.sy1==IVAR)
printf("%s\t,",ntab1[fexp[temp].arg1.pos]);
else
{
if(fexp[temp].arg1.sy1==TEMPVAR)
printf("T%d\t,",fexp[temp].arg1.pos);
else
{
if(fexp[temp].arg1.sy1==INTCONST)
printf("%d\t,",fexp[temp].arg1.pos);
else
printf("\t,");
}
}
if(fexp[temp].arg2.sy1==IVAR)
printf("%s\t,",ntab1[fexp[temp].arg2.pos]);
else
{
if(fexp[temp].arg2.sy1==TEMPVAR)
printf("T%d\t,",fexp[temp].arg2.pos);
else
{
if(fexp[temp].arg2.sy1==INTCONST)
printf("%d\t,",fexp[temp].arg2.pos);
else
printf("\t,");
}
}
if(fexp[temp].op[0]!='j')
{
if(fexp[temp].result>=100)
printf("T%d\t)",fexp[temp].result-100);
else
printf("%s\t)",ntab1[fexp[temp].result]);
}
else printf("%d\t)",fexp[temp].result);
if(temp==20)
{
printf("\n按任意键继续......\n");
getch();
}
printf("\n");
}
getch();
}
/*显示程序的统计信息*/
void showcount()
{
int temp;
printf("\n\n程序总共%d行,产生了%d个二元式!\n",programlinenum,count);
getch();
printf("\n====================变量名表====================\n");
for(temp=0;temp<tt1;temp++)
printf("%d\t%s\n",temp,ntab1[temp]);
getch();
}
/*主程序*/
main()
{
cfile=fopen("program.dat","r");/*读取待编译程序源文件*/
if(cfile==NULL){
printf("Can't open the file!\n");
exit(0);
}
readch();/* 从源文件读一个字符 */
scan();/* 词法分析 */
showworda();
showcount();
stack[sp].pos=0;
stack[sp].sy1=-1;/* 初始化状态栈 */
stack1[sp1]=0;/* 初始化状态栈1 */
oth.sy1=-1;
printf("\n==========状态栈加工过程及归约顺序==========\n");
readnu();/* 从二元式读入一个字符 */
lrparse();/* 四元式分析 */
getch();
show4result();
printf("\n程序运行结束\n");
getch();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -