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

📄 yufa.c

📁 编译原理课程设计
💻 C
字号:
/***************************
 语法分析
****************************/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<conio.h>
#define MAXSIZE  500				//栈大小
#define true 1
#define false 0

/*构造栈*/
typedef struct 
{
	char *ch_word[MAXSIZE];			//存放词文
	int st_place[MAXSIZE];			//语义信息
	int ch[MAXSIZE];				//存放符号(编号)
	int  sta[MAXSIZE];				//存放状态
	int  st_TC[MAXSIZE];
	int  st_FC[MAXSIZE];
	int	 top;
}stack;

struct formula
{
	char *opr;
	char *op1;
	char *op2;
	char *results;
	int result;

};
struct formula gen[MAXSIZE];

struct inds
{
	char *instr;					//字符串 
	int sty;						//类型
};
struct inds input[MAXSIZE];
int intop;							//指向当前输入串字符


int error;							//出错标志

/* 构造LR分析表*/

struct tableaction					//构造action分析表
{
	char c;							//动作
	int  s;							//状态
 }ACTION[63][29]={0};					

 int GOTO[48][15]={0};				//构造goto表

struct tableproduction				//构造产生式属性表
{
	int word_number;				//产生式左部编号
	int Pro_place;					//产生式左部符号的语义属性
	int word_count;					//产生式右部文法符号的个数
	int Pro_TC;
	int Pro_FC;
}production[33]={0};

char *string[MAXSIZE];				//符号表
int string_max=0;
char *tempvar[MAXSIZE];				//临时标量表
int tempvar_max;
int  tempvar_cur=0;

int T=0;
char *tempstr;
int NXQ=100;
int TS;								//栈顶状态号(TopStat)
int IS;								//当前输入符号(InpSym)
int NS;								//规约后GOTO产生的新状态(NewStat)
int PL;								//第i个产生式的左部(编号)(Production_left)

//入栈
void push(stack *st,char *chword,int x,int y,int z,int t,int f)
{
     if(st->top==MAXSIZE-1) printf("栈上溢 !\n");
	 else
	 {
		 st->top++;
		 st->ch_word[st->top]=chword;
		 st->st_place[st->top]=z;
		 st->ch[st->top]=x;
		 st->sta[st->top]=y;
		 st->st_TC[st->top]=t;
		 st->st_FC[st->top]=f;
	 }
}

//出栈
void pop(stack *st,int n)
{
	int i;
	for(i=0;i<n;i++)
	{
		if(st->top<0)
			printf("栈下溢出!\n");
		else
			st->top--;
	}
};

int Entry(char *buf)								//以buf为名查符号表
{            
    int i=0;
	int temp;
	for(i=0;i<string_max;i++)
	{
		if(strcmp(string[i],buf)==0)
			return(i);
	}
	string[string_max]=buf;
	temp=string_max;
	string_max++;
	printf("the %s is defined now",string[temp]);
	return(temp);
}
int NewTemp()
{
	int num;
	string[string_max]=tempvar[tempvar_cur];
	num=string_max;
	string_max++;
	tempvar_cur++;
	return num;
}
	
int Merge(int p1,int p2)
{
	int p;
	if(!p2)
		return p1;
	else
	{
		p=p2;
		while(gen[p].result)
			p=gen[p].result;
		gen[p].result=p1;
		return p2;
	}
}

void BackPatch(int p,int t)
{
	int q1;
	int q=p;
	while(q)
	{
		q1=gen[q].result;
		gen[q].result=t;
		q=q1;
	}
}

void act(stack *st,int num)
{
	
	if(num==6||num==7||num==28)//||num==2||num==3)
	{
		production[ACTION[TS][IS].s].Pro_place=Entry(st->ch_word[st->top]);
	}
	else if(num==5||num==8||num==9||num==23||num==24||num==25)
	{
		production[ACTION[TS][IS].s].Pro_place=st->st_place[st->top];
	}
	else if(num==10)
	{
		tempstr=(char *)malloc(3*sizeof(char));
		tempstr=":=";
		gen[NXQ].opr=tempstr;
		gen[NXQ].op1=st->ch_word[st->top-2];
		gen[NXQ].op2=string[st->st_place[st->top]];
		gen[NXQ].result=0;
		NXQ++;
//		printf("\nGEN(:= %s,0,%s)\n",st->ch_word[st->top-2],string[st->st_place[st->top]]);
	}
	else if(num==11)
	{
		production[ACTION[TS][IS].s].Pro_place=NewTemp();
		tempstr=(char *)malloc(2*sizeof(char));
		tempstr="+";
		gen[NXQ].opr=tempstr;
		gen[NXQ].op1=string[st->st_place[st->top-2]];
		gen[NXQ].op2=string[st->st_place[st->top]];
		gen[NXQ].results=string[production[ACTION[TS][IS].s].Pro_place];
		NXQ++;
//		printf("\nGEN(+ %s,%s,%s)\n",string[st->st_place[st->top-2]],string[st->st_place[st->top]],string[production[ACTION[TS][IS].s].Pro_place]);
	}
	else if(num==14)
	{
		production[ACTION[TS][IS].s].Pro_place=st->st_place[st->top-1];
	}
	else if(num==15)
	{
		BackPatch(st->st_TC[st->top],st->st_FC[st->top-1]);
		gen[NXQ].opr="j";
		gen[NXQ].op1="0";
		gen[NXQ].op2="0";
		gen[NXQ].result=st->st_FC[st->top-1];
		NXQ++;
		production[ACTION[TS][IS].s].Pro_TC=st->st_TC[st->top-1];
	}
	else if(num==17)
	{
		production[ACTION[TS][IS].s].Pro_TC=NXQ;
		production[ACTION[TS][IS].s].Pro_FC=NXQ+1;
		gen[NXQ].opr=string[st->st_place[st->top-1]];
		gen[NXQ].op1=string[st->st_place[st->top-2]];
		gen[NXQ].op2=string[st->st_place[st->top]];
		gen[NXQ].result=0;
		NXQ++;
		gen[NXQ].opr="j";
		gen[NXQ].op1="0";
		gen[NXQ].op2="0";
		gen[NXQ].result=0;
		NXQ++;
//		printf("\nGEN(%s,%s,%s,0)\n",string[st->st_place[st->top-1]],string[st->st_place[st->top-2]],string[st->st_place[st->top]]);
	}
	else if(num==18)
	{
		production[ACTION[TS][IS].s].Pro_TC=Merge(T,st->st_FC[st->top]);
	}
	else if(num==20)
	{
		BackPatch(st->st_TC[st->top-2],NXQ);
		gen[NXQ].opr="return";
		gen[NXQ].op1="0";
		gen[NXQ].op2="0";
		gen[NXQ].result=0;
		NXQ++;
		gen[NXQ].result=99;
		printf("success");
	}
	else if(num==22)
	{
		production[ACTION[TS][IS].s].Pro_TC=0;

	}
}
void LRdriver(stack *st)					//LR分析器驱动
{
	int l;
	TS=st->sta[st->top];				//栈顶状态号(TopStat)
	IS=input[intop].sty;				//当前输入符号(InpSym)
//	int NS;									//规约后GOTO产生的新状态(NewStat)
//	int PL;									//第i个产生式的左部(编号)(Production_left)	
	while((ACTION[TS][IS].c!='A')&&(!error))//A为acc
	{										/*输出分析过程*/
		printf("\n");						
		for(l=0;l<=st->top;l++)
			printf("%d",st->sta[l]);
		if(l>=6)
			printf("\t");
		else
			printf("\t\t");
		for(l=0;l<=st->top;l++)
			printf("%d",st->ch[l]);
		if(l>=6)
			printf("\t");
		else
			printf("\t\t");
		for(l=intop;input[l].sty!=100;l++)
			printf("%-s",input[l].instr);

		if(ACTION[TS][IS].c=='\0')			//分析动作为ERROR
		{
			error=1;
		}
		else if(ACTION[TS][IS].c=='S')		//分析动作为移进(s)
		{
			push(st,input[intop].instr,input[intop].sty,ACTION[TS][IS].s,0,0,0);
			if(input[intop].sty==6)
				BackPatch(st->st_TC[st->top-1],NXQ);
			else if(input[intop].sty==7)
			{
				T=NewTemp();
				T=Merge(NXQ,st->st_TC[st->top-1]);
				gen[NXQ].opr="j";
				gen[NXQ].op1="0";
				gen[NXQ].op2="0";
				gen[NXQ].result=0;
				NXQ++;
				BackPatch(st->st_FC[st->top-3],NXQ);
			}
			else if(input[intop].sty==8)
			{
				st->st_FC[st->top]=NXQ;
			}
			else if(input[intop].sty==9)
			{
				BackPatch(st->st_TC[st->top-1],NXQ);
				st->st_TC[st->top]=st->st_FC[st->top-1];
				st->st_FC[st->top]=st->st_FC[st->top-2];
			}
			intop++;
			printf("\ts%d",ACTION[TS][IS].s);
		}
		else if(ACTION[TS][IS].c=='r')		//分析动作为归约(r)
		{
			act(st,ACTION[TS][IS].s);
			pop(st,production[ACTION[TS][IS].s].word_count);
			PL=production[ACTION[TS][IS].s].word_number;//Production_left
			NS=GOTO[(st->sta[st->top])][production[ACTION[TS][IS].s].word_number-29];//(NewStat)
			push(st,input[intop].instr,PL,NS,production[ACTION[TS][IS].s].Pro_place,production[ACTION[TS][IS].s].Pro_TC,production[ACTION[TS][IS].s].Pro_FC);
			printf("\tr%d",ACTION[TS][IS].s);
		}
		TS=st->sta[st->top];
		IS=input[intop].sty;
	}
	if(!error)
	{
		printf("\n");
		for(l=0;l<=st->top;l++)
			printf("%d",st->sta[l]);
		printf("\t\t");
		for(l=0;l<=st->top;l++)
			printf("%d",st->ch[l]);
		printf("\t");
		for(l=intop;input[l].sty!=100;l++)
			printf("%s",input[l].instr);
		printf("\tAccepted!\n");
	}
	else
		printf("\nIt must be an error here,Please check it again!\n");
};


void yufa()
{	
	FILE *fpin;
	stack *st=(stack*)malloc(sizeof(stack));		//分析栈
	char file_token[]="token.txt";
	char file_goto[]="goto.txt";
	char file_action[]="action.txt";
	char file_proinfo[]="proinfo.txt";
	char file_infost[]="infost.txt";
	int x_location;									//x坐标
	int y_location;									//y坐标
	int goto_value;									//goto属性表中的状态值
	char action_act;								//action分析表中的动作
	int action_state;								//action分析表中的状态
	int pro_word_number;							//产生式属性表中的word_number
	int pro_word_count;								//产生式属性表中的word_count
	int i=0;
	int j=0;
	int t=0;
	tempstr=(char *)malloc(6*sizeof(char));	//暂存从token文件读出的词文
	for(t=0;t<MAXSIZE;t++)
	{
		st->ch[t]=100;
	}
	st->top =0;
	st->ch[0]=0;									//初始把'#'入栈
	st->sta[0]=0;
	if((fpin=fopen(file_token,"r"))==NULL)			/*读取token文件*/
		printf("Error:The file token is NULL");
	else
		do
		{
			if(fgetc(fpin)==EOF)
				break;
			else
			{
				fseek(fpin,-1L,1);
				fscanf(fpin,"%s %d",tempstr,&input[i].sty);
				input[i].instr=tempstr;
				printf("%s ",input[i].instr);
				i++;
				tempstr=(char *)malloc(6*sizeof(char));
			}
		}while(fgetc(fpin)!=EOF);
	fclose(fpin);
	input[i].instr='\0';								//结尾
	input[i].sty=100;
	intop=0;
	i=0;

	if((fpin=fopen(file_goto,"r"))==NULL)			/*读取goto文件,构造goto分析表*/
		printf("Error:The file goto is NULL");
	else
		do
		{
			if(fgetc(fpin)==EOF)
				break;
			else
			{
				fseek(fpin,-1L,1);
				fscanf(fpin,"%d %d %d",&x_location,&y_location,&goto_value);
				GOTO[x_location][y_location-29]=goto_value;			
			}
		}while(fgetc(fpin)!=EOF);
		fclose(fpin);

	if((fpin=fopen(file_action,"r"))==NULL)			/*读取action文件,构造action分析表*/
		printf("Error:The file action is NULL");
	else
		do
		{
			if(fgetc(fpin)==EOF)
				break;
			else
			{
				fseek(fpin,-1L,1);
				fscanf(fpin,"%d %d %c %d",&x_location,&y_location,&action_act,&action_state);
				ACTION[x_location][y_location].c=action_act;
				ACTION[x_location][y_location].s=action_state;
			}
		}while(fgetc(fpin)!=EOF);
	fclose(fpin);

	if((fpin=fopen(file_proinfo,"r"))==NULL)		/*读取proinfo文件,构造产生式属性表*/
		printf("Error:The file proinfo is NULL");
	else
		do
		{
			if(fgetc(fpin)==EOF)
				break;
			else
			{
				fseek(fpin,-1L,1);
				fscanf(fpin,"%d %d %d",&x_location,&pro_word_number,&pro_word_count);
				production[x_location].word_number=pro_word_number;
				production[x_location].word_count=pro_word_count;
			}
		}while(fgetc(fpin)!=EOF);
	fclose(fpin);

	i=0;
	if((fpin=fopen("id.txt","r"))==NULL)		/*读取文件,构造产生式属性表*/
		printf("Error:The file proinfo is NULL");
	else
		do
		{
			if(fgetc(fpin)==EOF)
				break;
			else
			{
				fseek(fpin,-1L,1);
				tempstr=(char *)malloc(5*sizeof(char));
				fscanf(fpin,"%s",tempstr);
				string[i]=tempstr;
				i++;
			}
		}while(fgetc(fpin)!=EOF);
	string[i]='\0';
	string_max=i;

	i=0;
	if((fpin=fopen("temp_id.txt","r"))==NULL)		/*读取文件,构造产生式属性表*/
		printf("Error:The file temp_id is NULL");
	else
		do
		{
			if(fgetc(fpin)==EOF)
				break;
			else
			{
				fseek(fpin,-1L,1);
				tempstr=(char *)malloc(3*sizeof(char));
				fscanf(fpin,"%s",tempstr);
				tempvar[i]=tempstr;
				i++;
			}
		}while(fgetc(fpin)!=EOF);
	tempvar[i]='\0';
	tempvar_max=i;
/*
	for(i=0;i<15;i++)
		nterm[i].nt_num=(i+29);
*/
	i=0;
	printf("\n状态栈\t\t符号栈\t\t余留串\t\t\t动作");
//	printf("\n产生的四元式为:\n");
	LRdriver(st);
	for(i=100;gen[i].result!=99;i++)
	{
		if(gen[i].results!=NULL)
			printf("%d:GEN(%s,%s,%s,%s)\n",i,gen[i].opr,gen[i].op1,gen[i].op2,gen[i].results);
		else
			printf("%d:GEN(%s,%s,%s,%d)\n",i,gen[i].opr,gen[i].op1,gen[i].op2,gen[i].result);
	}
}

⌨️ 快捷键说明

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