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

📄 recuranalyser.c

📁 1.1 引言 1.1.1 设计目的 本次课程设计是在完成一个学期的编译原理课程之后
💻 C
📖 第 1 页 / 共 2 页
字号:
/******************************************************************************
*所属模块名:递归下降分析器
*
*功能:判定源程序中程序结构语句是否符合语法规则
*       
*开始时间: 2004.10.29      
*
*修改时间:2004.11.18,11.25,11.27,11.28
*     
*完成时间:2004.11.28
*
*作者: 邸晓峰      
*      
*       

*******************************************************************************/
#include "WordAnalyser.c"

//全局变量
Duatype WORD;				//读入单词符号
vtable VariableTable;		//变量表
ptable ProcTable;			//过程名表
my_stack ProcStack;			//过程栈,用于查过程名表 
int level;					//当前分析所在过程深度
int	counter;					//变量相对个数
int errflag_prog;
char errtext[19][20];		//错误信息存储区

bool isTrue;				//如果语法分析出现错误,则置为false,不再产生四元式。
int PC;						//四元式表指针
void LRAnalyser();
void GEN(int strOperator,Operand op1,Operand op2,Operand op3);
//////////////////////////////////////////////////////////////////////////////////////////////
//此函数初始化全局变量
void init(){
	FILE* perrfile;
	char temp;
	int bufpoint,textpoint;
	isTrue=true;
	perrfile=fopen("error.txt","r");
	for(textpoint=0;textpoint<19;textpoint++){
		bufpoint=0;
		temp=fgetc(perrfile);
		while(temp!='\n'){							//和文件存储有关
			errtext[textpoint][bufpoint]=temp;
			bufpoint++;
			temp=fgetc(perrfile);
		}
		errtext[textpoint][bufpoint]='\0';
	}
	fclose(perrfile);
	level=0;										
	counter=1;
	linenum=1;
	VariableTable.first=0;
	VariableTable.last=49;
	ProcTable.pointer=-1;							//便于后续处理
	errflag_prog=false;
	ProcStack.base=ProcStack.top=(stack_item*)malloc(sizeof(stack_item));	//初始化栈
	ProcStack.base->index=0;
	ProcStack.base->next=NULL;
}

//////////////////////////////////////////////////////////////////////////////////////////////
//此函数从二元式链表中读出一个单词符号,放入WORD中
void getWord(){
	Duatype* temp;
	if(Dualist.head->next==NULL){		//二元式链表读完,WORD.index=0作为标志
		WORD.index=0;
		Dualist.tail=Dualist.head;
	}
	else{
		temp=Dualist.head->next;
		Dualist.head->next=temp->next;		//从链表中删除已读二元式
		while(temp->index==35){
			linenum++;
			free(temp);
			temp=Dualist.head->next;
			if(temp==NULL)
				break;
			Dualist.head->next=temp->next;
		}
		if(temp==NULL){		//二元式链表读完,WORD.index=0作为标志
			WORD.index=0;
			Dualist.tail=Dualist.head;
		}
		else{
			WORD.value=(char*)malloc((strlen(temp->value)+1)*sizeof(char));
			strcpy(WORD.value,temp->value);			//读入单词所在二元式
			WORD.index=temp->index;
			free(temp);							//释放已读二元式空间
		}
	}
}

//////////////////////////////////////////////////////////////////////////////////////////////
//入栈函数
void push(){
	ProcStack.top->next=(stack_item*)malloc(sizeof(stack_item));
	ProcStack.top=ProcStack.top->next;
	ProcStack.top->index=ProcTable.pointer;
	ProcStack.top->next=NULL;
}

//////////////////////////////////////////////////////////////////////////////////////////////
//出栈函数
void pop(){
	stack_item* p=ProcStack.base;
	if(p!=ProcStack.top){
		while(p->next!=ProcStack.top)
			p=p->next;
		p->next=NULL;
		free(ProcStack.top);
		ProcStack.top=p;
	}
}

//////////////////////////////////////////////////////////////////////////////////////////////
//此函数跳过一些单词,直到读入指定的单词
//参数为索引值,按索引值跳到相应的单词
void skip(int index){
	switch(index){
	case 1:									//jump to begin
		while(WORD.index!=4){
			getWord();
			if(WORD.index==0)
				break;
		}
		break;
	case 2:									//jump to procedure or begin
		while(WORD.index!=3 && WORD.index!=4){
			getWord();
			if(WORD.index==0)
				break;
		}
		break;
	case 3:									//jump to var or procedure or begin
		while(WORD.index!=2 && WORD.index!=3 && WORD.index!=4){
			getWord();
			if(WORD.index==0)
				break;
		}
		break;
	}
}

//////////////////////////////////////////////////////////////////////////////////////////////
//此函数错误处理函数
//参数为索引值,表示正常执行第几条错误处理
void error_handle(int index){
	printf("Error:第%d行,%s\n",linenum,errtext[index]);
	isTrue=false;
}
	
//////////////////////////////////////////////////////////////////////////////////////////////
//此函数填写变量名表
//参数为0表示正常填入,为1标识倒填
void enterVTable(int flag){
	int tempointer;
	int i;
	tempointer=VariableTable.first;
	switch(flag){
	case 0:					//正常顺序填入
		if(VariableTable.first>VariableTable.last){
			error_handle(17);			//越界处理
			return;
		}
		else{
			if(counter==1)			//若是本过程第一个变量则填过程名表第一个变量所在位置first值
				ProcTable.table[ProcTable.pointer].firstinvtable=VariableTable.first;
			else{					//若不是本过程第一个变量则查本过程内是否有同名变量
				for(i=ProcTable.table[ProcTable.pointer].firstinvtable;i<tempointer;i++)
					if(strcmp(VariableTable.table[i].vname,WORD.value)==0){
						error_handle(13);
						return;
					}
			}
			VariableTable.table[tempointer].vname=(char*)malloc((strlen(WORD.value)+1)*sizeof(char));
			strcpy(VariableTable.table[tempointer].vname,WORD.value);	//填变量名
			free(WORD.value);
			VariableTable.table[tempointer].plevel=level;				//填嵌套深度
			VariableTable.table[tempointer].relposition=counter;			//填相对个数
			counter++;	
			VariableTable.first++;			
			break;
		}
	case 1:					//倒填
		if(VariableTable.last<VariableTable.first){
			error_handle(17);			//越界处理
			break;
		}
		else{
			VariableTable.table[VariableTable.last].vname=(char*)malloc((strlen(WORD.value)+1)*sizeof(char));
			strcpy(VariableTable.table[tempointer].vname,WORD.value);	//填变量名
			free(WORD.value);
			VariableTable.last--;			
			break;
		}
	}
}

//////////////////////////////////////////////////////////////////////////////////////////////
//此函数在执行语句中遇到变量去查变量名表看是否已定义
//参数变量名,返回置为-1表示没查到,查到则返回在变量名表中的下标
int searchVTable(char *v){
	int currentproc;
	int firstvar;
	int sumvar;
	int i;
	currentproc=ProcStack.top->index;
	while(currentproc!=-1){
		firstvar=ProcTable.table[currentproc].firstinvtable;
		sumvar=ProcTable.table[currentproc].variablenum;
		for(i=firstvar;i<firstvar+sumvar;i++)
			if(strcmp(VariableTable.table[i].vname,v)==0)
				return i;
		currentproc=ProcTable.table[currentproc].outposition;
	}
	for(i=49;i>VariableTable.last;i--)
		if(strcmp(VariableTable.table[i].vname,v)==0)
			return i;
	error_handle(15);
	return -1;
}

//////////////////////////////////////////////////////////////////////////////////////////////
//此函数在填过程名表前去查过程名表看是否已定义
//参数变量名,返回置为-1表示没查到,查到则返回在过程名表中的下标
int searchPTable(char* name){
	int i;
	for(i=ProcTable.pointer;i>=0;i--){
		if(strcmp(ProcTable.table[i].pname,name)==0){
			error_handle(14);
			return i;
		}
	}
	return -1;
}

//////////////////////////////////////////////////////////////////////////////////////////////
//此函数填写过程名表
void enterPTable(){
	int templevel;
	int tempindex;
	if(searchPTable(WORD.value)==-1){			//过程名不重名
		ProcTable.pointer=ProcTable.pointer+1;
		ProcTable.table[ProcTable.pointer].pname=(char*)malloc((strlen(WORD.value)+1)*sizeof(char));
		strcpy(ProcTable.table[ProcTable.pointer].pname,WORD.value);		//填过程名
		free(WORD.value);
		ProcTable.table[ProcTable.pointer].plevel=level;			//填嵌套深度
		ProcTable.table[ProcTable.pointer].paranum=0;				//参数个数初始为0,后续可能修改
		ProcTable.table[ProcTable.pointer].variablenum=0;			//变量总数初始为0,后续可能修改
		if(ProcTable.pointer==0)									//填外过程位置
			ProcTable.table[ProcTable.pointer].outposition=-1;		//主程序外过程规定为-1
		else{
			if(level==ProcTable.table[ProcTable.pointer-1].plevel)
				ProcTable.table[ProcTable.pointer].outposition=ProcTable.table[ProcTable.pointer-1].outposition;
			else if(level>ProcTable.table[ProcTable.pointer-1].plevel)
				ProcTable.table[ProcTable.pointer].outposition=ProcTable.pointer-1;
			else{
				templevel=ProcTable.table[ProcTable.pointer-1].plevel;
				tempindex=ProcTable.pointer-1;
				while(level!=templevel){
					tempindex=ProcTable.table[tempindex].outposition;
					templevel=ProcTable.table[tempindex].plevel;
				}
				ProcTable.table[ProcTable.pointer].outposition=ProcTable.table[tempindex].outposition;
			}
		}
	}
}

void recurPRP();
//////////////////////////////////////////////////////////////////////////////////////////////
//PARL(参数说明)的递归下降分析子程序

⌨️ 快捷键说明

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