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

📄 算符优先分析.cpp

📁 编译器中算符优先算法的简单实现
💻 CPP
字号:
// 算符优先分析.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "parser.h"

/**************
文法G[E]描述:   
E→E+T∣E-T∣T    
T→T*F∣T/F∣F
F→(E)∣i
**************/

/*************算符优先关系表************/
/*  |  +   -   *   /   (   )   i   #  */
/*--|---------------------------------*/
/* +|  >   >   <   <   <   >   <   >  */
/* -|  >   >   <   <   <   >   <   >  */
/* *|  >   >   >   >   <   >   <   >  */
/* /|  >   >   >   >   <   >   <   >  */
/* (|  <   <   <   <   <   =   <      */
/* )|  >   >   >   >       >       >  */
/* i|  >   >   >   >       >       >  */
/* #|  <   <   <   <   <       <   =  */
/*-------------------------------------*/


//读入实验一中的二元式文件内容并完成转换
void ReadBuff()
{
	char in[20];
	FILE *infile;
	do{
		printf("\n请输入需要分析的源文件路径:");
		scanf("%s",&in);
		infile = fopen(in, "r");
		if(infile==NULL) 
			printf("\n出错:未找到源文件,请再次输入源文件路径!\n\n");
	}while(infile==NULL);
	
	int id = 0, i = 0;
	char b[20];
	do{	
		fgets(b,20,infile); 
		char *cc; 
		cc = strtok(b,","); 
		id = atoi(cc);
		switch(id){ //标号转换过程
		case 12:
		case 13:
			a[i++] = 'i';
			break;
		case 25:
			a[i++] = '/';
			break;
		case 26:
			a[i++] = '+';
			break;
		case 27:
			a[i++] = '-';
			break;
		case 28:
			a[i++] = '*';
			break;
		case 30:
			a[i++] = '(';
			break;
		case 31:
			a[i++] = ')';
			break;
		default:
			break;
		} 
	}while(id != 0 && i <= 50);
	printf("\n转换为文法对应形式:%s\n\n",a);
	
	int n = strlen(a);
	a[n++] = '#';
}

//打印分析过程
void printStep(int step, int k, char NewVn, char cc[])
{
	printf("%3d",step);
	printf("\t\t");
	for(int m=0; m<=k; m++)
		printf("%c",stack[m]);
	if(m>8)
		printf("\t%s",cc);
	else
		printf("\t\t%s",cc);
	printf("\t\t\t%c",NewVn);
	printf("\n");

}

//算符优先分析过程
bool parser()
{
//	printf("输入字符:");
//	scanf("%s",a);
	
	//读入二元式文件并完成转换
	ReadBuff();

	int i,k;      //i:当前分析字符的下标位置,k:比较字符在栈的下标位置
	char NewVn;   //NewVn:规约产生式形成的左部
	char r;       //r:当前分析的字符
	int step;	  //step:当前分析的步骤数
	i = 0;   
	k = 0;  
	step = 0;
	stack[0] = '#';

	char cc[10] = "";  //cc:记录规约的产生式右部
	printf("步骤         分析栈内容      当前规约的最左子串    规约所得到符号\n");
	
	do{
		int j;
		r = a[i++];    //r指向输入串中正在分析的字母 
		
		if(IsVt(stack[k]))  //如果当前栈顶是终结符 
			j = k;            //取栈顶元素   
		else
			j = k-1;          //取栈顶下一元素
		
		while((stack[j] != '#') && (IsHigherThan(stack[j],r)))   //归约到不能再归约
		{
			char q;
			do{
				q = stack[j];
				
				if(IsVt(stack[j-1]))
					j--;
				else
					j-=2;	
			}while(!IsLowerThan(stack[j],q));//从栈顶向下找到最左素短语
			
			//将stack[j+1]stack[j+2]...stack[k]进行归约
			NewVn = Reduce(j+1,k,k-j);
			for(int l=0; l<k-j; l++)
				cc[l] = stack[j+1+l];
			cc[l] = '\0';
			if(NewVn == ' ')
				return ERROR;
			k = j+1; 
			stack[k] = NewVn; 
			step++;
			printStep(step,k,NewVn,cc);
			NewVn = ' ';
		}/*while*/
		
		if(IsLowerThan(stack[j],r) || IsEqualTo(stack[j],r))
		{
			k++;
			stack[k] = r;  //当前分析字符入栈
		}
		else
			return ERROR;
	}while(r != '#');
	step++;
	printf("%3d",step);
	printf("\t\t");
	for(int m=0; m<=k; m++)
		printf("%c",stack[m]);
	printf("\t\t分析成功");
	printf("\n");
	return SUCCESS;
}

int main(int argc, char* argv[])
{
	int c=0;
	printf("************************\n");
	printf("************************\n");
	printf("------------------------\n");
	printf("************************\n");
	printf("** <文法描述>         **\n");
	printf("**  1:E→E+T∣E-T∣T  **\n");
	printf("**  2:T→T*F∣T/F∣F  **\n");
	printf("**  3:F→(E)∣i       **\n");
	printf("************************\n");
	do{
		printf("\n请选择:1-> 算符优先分析   2-> 退出\n");
		scanf("%d",&c);
		if(c==1){
			if(parser())
				printf("\n分析结果:输入串合法!\n");
			else
				printf("\n分析结果:输入串非法!\n");
		}else if(c==2)
			break;
		else printf("\n请选择正确选项!\n");
	}while(true);
	
	return 0;
}

⌨️ 快捷键说明

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