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

📄 实验3.cpp

📁 中间代码生成 掌握语学制导下的中间代码生成技术
💻 CPP
📖 第 1 页 / 共 2 页
字号:

void prior_analysis()//自下而上分析
{
    int i,j,m;
    char q,str,ch[10];   
	push('#');//设置符号栈初值
	print(0,-1);	    
u:  readvt(&a);//当前输入符号读入a
    if(IsVT(stack[top]))//判断是否为终结符
        j=top;
    else
        j=top-1;
	do 
	{	
        while(big(j,a)&&strcmp(stack,"#N")!=0)//j优先级高于a
		{
            do 
			{
                q=stack[j];
                if(IsVT(stack[j-1]))//判断是否为终结符
                    j=j-1;
                else
                    j=j-2;
			}while(!less(j,q));
			i=-1;
			while((top-j)!=0)
			{
                ch[++i]=pop();
			}
			ch[i+1]='\0';
			for (m=0;m<=5;m++)//把最左素短语归约为某个N
			{
				if(strcmp(word[m],ch)==0)
					str='N';
			}
			push(str);
            print(1,1);
		}
        if(less(j,a))//j优先级低于a
		{         
            push(a);
			print(0,-1);
			if(stack[top]!='#')
				goto u;
		}
        else
		{
            if(equal(j,a))//j优先级等于a
			{        
                push(a);
				print(0,0);
			    if(stack[top]!='#')
					goto u;
			}
			else
			{
				error1(j);//调用错误分析函数
				a='#';
			}
		}
	}while(a!='#');
}

//////////////////////////////////////////////////////////////////////////////////////////

void suanfu()//算符优先语法主函数
{
    cout<<"\n******************************算符优先语法分析程序******************************"<<endl;
	cout<<" E->E+T|E-T|T"<<endl;
	cout<<" T->T*F|T/F|F"<<endl;
	cout<<" F->(E)|i"<<endl;
	cout<<" E表示算术表达式.T表示项.F表示因子.i表示变量或常数."<<endl;
	cout<<"              优先表"<<endl;
	cout<<"     +   -   *   /   (   )   i   #"<<endl;
	cout<<" +   >   >   <   <   <   >   <   >"<<endl;
    cout<<" -   >   >   <   <   <   >   <   >"<<endl;
	cout<<" *   >   >   >   >   <   >   <   >"<<endl;
	cout<<" /   >   >   >   >   <   >   <   >"<<endl;
	cout<<" (   <   <   <   <   <   =   <   e1"<<endl;
	cout<<" )   >   >   >   >   e2  >   e2  >"<<endl;
	cout<<" i   >   >   >   >   e2  >   e2  >"<<endl;
	cout<<" #   <   <   <   <   <   e3  <   ="<<endl;
	ff=fopen("预处理.txt","r");
	char ch=fgetc(ff);
	char ch1;
	while(ch!='#')
	{
	    int i=-1,j=0,m=-1;
	    while(ch!='='&&ch!='#')
		{
			ch1=ch;
			ch=fgetc(ff);
			if((ch1=='>'||ch1=='<')&&ch=='=')
				ch=fgetc(ff);
		}
		if(ch=='#')
		{
		    cout<<endl;
			fclose(ff);
		    return;
		}
	    while(ch!=' '&&ch!='#')//得到算数表达式
		{
		    ch=fgetc(ff);
            oldstrings[++i]=ch;
		}
	    oldstrings[i]='\0';
	    if(isalnum(oldstrings[j]))
	        strings[++m]='i';
	    else
		    strings[++m]=oldstrings[j];
	    j++;
	    while(oldstrings[j]!='\0')//转换为输入串
		{
            if(isalnum(oldstrings[j]))
			{
			    if(isalnum(oldstrings[j-1])==0)
			        strings[++m]='i';
			}
		    else
			    strings[++m]=oldstrings[j];
		    j++;
		}
	    strings[m+1]='#';
	    strings[m+2]='\0';
	    cout<<"算术表达式"<<id<<"为: "<<oldstrings<<endl;
        cout<<"转换为输入串: "<<strings<<endl;	
        cout<<" 步骤号 符号栈 优先关系 当前分析符 剩余输入串 动作";
	    prior_analysis();//自下而上分析
	    n=0;
		cout<<endl;
	    cout<<"算术表达式"<<id++<<"的"<<"归约产生式步骤号为:";
   	    while(No[n])//记录归约产生式步骤号
		{
		    cout<<" "<<No[n];
	        n++;
		}
		cout<<endl;
		//回归各全局变量初值
        while(stack[0]!='\0')
		    pop();
		while(No[--n])
		{
			No[n]='\0';
		}
	    top=-1;
	    a='\0';
	    k=0;
	    step=1;
	    n=0;
	}
}

/***********************************以下是语义分析部分***********************************/

//////////////////////////////////////////////////////////////////////////////////////////

void error(char *strError)//输出扫描发现的错误
{
	fprintf(fw,"错误: %s\n",strError);
	printf("错误: %s\n",strError);
	return;
}

//////////////////////////////////////////////////////////////////////////////////////////

int Match(char syn,char *strError)//匹配当前识别出的单词
{
	if(syn==uWord.syn&&(strcmp(strError,uWord.value.T1)==0)||strError[0]==uWord.value.T3)
	{
		Scaner();
		return 1;
	}
	else 
	{
		error(strError);
	    return 0;
	}
}

//////////////////////////////////////////////////////////////////////////////////////////

void gen(char *op,char *argv1,char *argv2,char *result)//生成一个四元式
{
	sprintf(pQuad[nNXQ].op,op);
	sprintf(pQuad[nNXQ].argv1,argv1);
	sprintf(pQuad[nNXQ].argv2,argv2);
	sprintf(pQuad[nNXQ].result,result);
	nNXQ++;
	return;
}

//////////////////////////////////////////////////////////////////////////////////////////

void PrintQuaternion()//打印四元式数组
{
	int nLoop;
	printf("********************************中间代码生成程序********************************");
	for(nLoop=1;nLoop<nNXQ;nLoop++)
	{
		fprintf(fw,"\n%d:(%s,\t%s,\t%s,\t%s)",
			nLoop,pQuad[nLoop].op,pQuad[nLoop].argv1,
			pQuad[nLoop].argv2,pQuad[nLoop].result);
		printf("\n%d:(%s,\t%s,\t%s,\t%s)",
			nLoop,pQuad[nLoop].op,pQuad[nLoop].argv1,
			pQuad[nLoop].argv2,pQuad[nLoop].result);
	}
}

//////////////////////////////////////////////////////////////////////////////////////////

char *Newtemp()//产生一个临时变量
{
	char *strTempID=(char *)malloc(MAXLENGTH);
	sprintf(strTempID,"T%d",++nSuffix);
	return strTempID;
}

//////////////////////////////////////////////////////////////////////////////////////////

int merge(int p1,int p2)//合并p1和p2
{
	int p,nResult;
	if(p2==0)
		nResult=p1;
	else
	{
		nResult=p=p2;
		while(atoi(pQuad[p].result))
		{
			p=atoi(pQuad[p].result);
			sprintf(pQuad[p].result,"%d",p1);
		}
	}
	return nResult;
}

//////////////////////////////////////////////////////////////////////////////////////////

void backpatch(int p,int t)//将t回填到以p为首的四元式中
{
	int w,q=p;
	while(q)
	{
		w=atoi(pQuad[q].result);
		sprintf(pQuad[q].result,"%d",t);
		q=w;
	}
}

//////////////////////////////////////////////////////////////////////////////////////////

char *Expression()//分析算术表达式函数
{
	char opp[MAXLENGTH],*eplace,*eplace1,*eplace2;		
	eplace=eplace1=Term();
	while(uWord.syn=='O'&&(strcmp(uWord.value.T1,"+")==0||strcmp(uWord.value.T1,"-")==0))
	{
		sprintf(opp,"%s",uWord.value.T1);
		Scaner();
		eplace2=Term();
		eplace=Newtemp();
		gen(opp,eplace1,eplace2,eplace);
		eplace1=eplace;
	}
	return eplace;
}

//////////////////////////////////////////////////////////////////////////////////////////

char *Term()//分析项函数
{
	char opp[2],*eplace1,*eplace2,*eplace;
	eplace=eplace1=Factor();
	while(uWord.syn=='O'&&(strcmp(uWord.value.T1,"*")==0||strcmp(uWord.value.T1,"/")==0))
	{
		sprintf(opp,"%s",uWord.value.T1);
		Scaner();
		eplace2=Factor();
		eplace=Newtemp();
		gen(opp,eplace1,eplace2,eplace);
		eplace1=eplace;
	}
	return eplace;
}

//////////////////////////////////////////////////////////////////////////////////////////

char *Factor()//分析因子函数
{
	char *eplace=(char *)malloc(MAXLENGTH);
	if(uWord.syn=='I'||uWord.syn=='C')
	{
		if(uWord.syn=='I')
			sprintf(eplace,"%s",uWord.value.T1);
		else
			sprintf(eplace,"%d",uWord.value.T2);
		Scaner();
	}
	else
	{
		Match('P',"(");
		eplace=Expression();
		Match('P',")");
	}
	return eplace;
}

//////////////////////////////////////////////////////////////////////////////////////////

void Condition(int *etc,int *efc)//分析布尔表达式函数
{
	char opp[3],*eplace1,*eplace2;
	char strTemp[4];
	eplace1=Expression();
	if(uWord.syn=='O'&&(strcmp(uWord.value.T1,"+")!=0&&strcmp(uWord.value.T1,"-")!=0
		&&strcmp(uWord.value.T1,"*")!=0&&strcmp(uWord.value.T1,"/")!=0))
	{
		sprintf(opp,"%s",uWord.value.T1);
		Scaner();
		eplace2=Expression();
		*etc=nNXQ;
		*efc=nNXQ+1;
		sprintf(strTemp,"j%s",opp);
		gen(strTemp,eplace1,eplace2,"0");
		gen("j","","","0");
	}
	else
		error("关系运算符");
}

//////////////////////////////////////////////////////////////////////////////////////////

void Statement(int nChain)//语句分析函数
{
	char strTemp[MAXLENGTH],eplace[MAXLENGTH];
	int nChainTemp=0,nChainTemp1=0,nWQUAD,Temp,tag2;
	switch(uWord.syn)
	{
	    case 'I'://赋值语句分析
			strcpy(strTemp,uWord.value.T1);
			Scaner();
			Match('O',"=");
			strcpy(eplace,Expression());
			gen("=",eplace,"",strTemp);
			nChain=0;
			break;
		case 'L'://带标号的赋值语句分析
			Scaner();
			Match('P',":");
			strcpy(strTemp,uWord.value.T1);
			Scaner();
			Match('O',"=");
			tag1=nNXQ;
		    strcpy(eplace,Expression());
			gen("=",eplace,"",strTemp);
			nChain=0;
			break;
		case 'K':
			if(strcmp(uWord.value.T1,"IF")==0)//IF-THEN条件语句分析
			{
			    Match('K',"IF");
			    Match('P',"(");
			    Condition(&ntc,&nfc);
			    backpatch(ntc,nNXQ);
			    Match('P',")");
				Match('K',"THEN");
			    Statement(nChainTemp);			
				if(strcmp(uWord.value.T1,"ELSE")!=0)
				    backpatch(nfc,nNXQ);
			    nChain=merge(nChainTemp,nfc);
			}
		    if(strcmp(uWord.value.T1,"ELSE")==0)//IF-THEN-ELSE条件语句分析
			{
				gen("j","","","0");
			    nWQUAD=nNXQ;
				tag2=nNXQ-1;
				backpatch(nfc,nWQUAD);
				Temp=merge(nWQUAD,nChainTemp);				
				Match('K',"ELSE");
                Statement(nChainTemp);
				backpatch(tag2,nNXQ);
                nChain=merge(Temp,nChainTemp1);
			}
			if(strcmp(uWord.value.T1,"GOTO")==0)//转移语句分析
			{
			    Match('K',"GOTO");
				nWQUAD=nNXQ;
				gen("j","","","0");
				backpatch(nWQUAD,tag1);
                nChain=0;
			}		
            break;
	}
}

//////////////////////////////////////////////////////////////////////////////////////////

void Statement_Sequence(int nChain)//语句串分析函数
{
	Statement(nChain);
	while((uWord.syn=='I'||uWord.syn=='L'
		||(uWord.syn=='K'&&strcmp(uWord.value.T1,"IF")==0)
		||(uWord.syn=='K'&&strcmp(uWord.value.T1,"ELSE")==0)
		||(uWord.syn=='K'&&strcmp(uWord.value.T1,"GOTO")==0))&&strcmp(uWord.value.T1,"end")!=0)
	{
		Statement(nChain);
	}
}

//////////////////////////////////////////////////////////////////////////////////////////

void Parse()//分析生成中间代码
{
	int nChain=0;
	str=fgetc(fp);
	Scaner();
	Statement_Sequence(nChain);
	if(strcmp(uWord.value.T1,"end")!=0)
	{		
		printf("\n源程序非正常结束");
		fprintf(fw,"\n源程序非正常结束");
	}
	suanfu();//调用算符优先语法主函数
	PrintQuaternion();//打印四元式数组
}

/************************************以下是主函数部分************************************/

//////////////////////////////////////////////////////////////////////////////////////////

void main()//主函数
{
	pQuad=(QUATERNION *)malloc(4*MAXLENGTH);
	nSuffix=0;
	nfc=ntc=nNXQ=1;
	char buf[4048]={'\0'};
	int i=0;  
    out=fopen("二元式表.txt","w");
	in=fopen("预处理.txt","w");
	printf("请输入源文件路径及名称:");
	scanf("%s",filename);	
    if ((fp=fopen(filename,"rt"))==NULL)        
	{
		printf("源文件无法打开!\n");
		system("pause");
	    exit(0);
	}
    else
	{
		printf("**********************************词法分析程序**********************************\n");
	    printf("K:关键字 I:标识符 C:常数 O:运算符 P:界符 L:标号\n");
		pro_process(buf);//生成预处理文件
		while (buf[i]!='#')
		{
			fputc(buf[i],in);
			i++;
		}
		fputc('#',in);
		fclose(in);
		fp=fopen("预处理.txt","r");
	}		
	fw=fopen("四元式表.txt","w");	
	Parse();//分析生成中间代码
	cout<<endl;
	fclose(fw);
	fclose(fp);
    cout<<"输出结果保存在二元式表.txt和四元式表.txt文件中,请打开查看。"<<endl;
	system("pause");
	exit(0);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -