⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 analyzer.c

📁 编译原理实验程序C语言版本
💻 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 + -