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

📄 util.h

📁 为编译原理课程设计
💻 H
字号:
int checkOpenFiles(int count,char** vars)
{
	fp_source=fopen("test.pas","rb");
		fp_output=fopen("output","wb");
		return 0; 
	if(count!=3)
	{
		printf("错误:请将参数输入完整\n");
		return 4;
	}
	else
	{
		
		if((fp_source=fopen(vars[1],"rb"))==NULL)
		{
			printf("错误:不能打开源程序文件\n");
			return 1;
		}
		if((fp_output=fopen(vars[2],"wb"))==NULL)
		{
			printf("错误:不能打开单词输出文件\n");
			return 2;
		}
		
		

		/*
		if((fp_wordList=fopen(vars[3],"rb"))==NULL)
		{
			printf("错误:不能打开语法配置文件\n");
			return 3;
		}
		*/
		return 0;
	}
}




void initiate(FILE *fp_wordList_p)
{
			
/*
	int loop_i;
	
	fread(&wordCount,sizeof(int),1,fp_wordList_p);	//配置文件开始的第一个INT型数据代表共有多少个单词编码。
	
	fread(&doubleop_count,sizeof(int),1,fp_wordList_p);		//配置文件的第二个INT型数据代码共有多少个由两个字符组成的运算符
	
	if(doubleop_count!=0)
	{
		DoubleOperand=(char *)malloc(sizeof(char) * doubleop_count);
		malloc_DO=1;

		for(loop_i=0;loop_i<doubleop_count;loop_i++)
		{
			fread(DoubleOperand+loop_i,sizeof(char),1,fp_wordList_p);
			//printf("%c",*(DoubleOperand+loop_i));
		}

	}
	
	if(wordCount!=0)
	{
		p_wordlist=(WORD_LIST_ITEM *)malloc(sizeof(WORD_LIST_ITEM) * wordCount);
		malloc_WL=1;
		
		for(loop_i=0;loop_i<35;loop_i++)
		{
			
			fread(p_wordlist+loop_i,sizeof(WORD_LIST_ITEM),1,fp_wordList_p);
			//printf("%s\t\t%d\n",(p_wordlist +loop_i)->name,(p_wordlist +loop_i)->type);

			if(strcmp((p_wordlist+loop_i)->name,"ident")==0)
				code_ident=(p_wordlist+loop_i)->type;
			else if(strcmp((p_wordlist+loop_i)->name,"const")==0)
				code_const=(p_wordlist+loop_i)->type;
			else if((p_wordlist+loop_i)->name=="\n")
				code_crlf=(p_wordlist+loop_i)->type;
		}
		
	}
*/
	int i;
	strcpy(p_wordlist[0].name,"program");

	strcpy(p_wordlist[1].name,"var");

	strcpy(p_wordlist[2].name,"procedure");

	strcpy(p_wordlist[3].name,"begin");

	strcpy(p_wordlist[4].name,"end");

	strcpy(p_wordlist[5].name,"if");

	strcpy(p_wordlist[6].name,"then");

	strcpy(p_wordlist[7].name,"else");

	strcpy(p_wordlist[8].name,"while");

	strcpy(p_wordlist[9].name,"do");

	strcpy(p_wordlist[10].name,"for");

	strcpy(p_wordlist[11].name,"step");

	strcpy(p_wordlist[12].name,"until");

	strcpy(p_wordlist[13].name,"call");

	strcpy(p_wordlist[14].name,"read");

	strcpy(p_wordlist[15].name,"write");

	strcpy(p_wordlist[16].name,"ident");

	strcpy(p_wordlist[17].name,"const");

	strcpy(p_wordlist[18].name,"+");

	strcpy(p_wordlist[19].name,"-");

	strcpy(p_wordlist[20].name,"*");

	strcpy(p_wordlist[21].name,"/");

	strcpy(p_wordlist[22].name,":=");

	strcpy(p_wordlist[23].name,"=");

	strcpy(p_wordlist[24].name,"<>");

	strcpy(p_wordlist[25].name,">");

	strcpy(p_wordlist[26].name,">=");

	strcpy(p_wordlist[27].name,"<");

	strcpy(p_wordlist[28].name,"<=");

	strcpy(p_wordlist[29].name,"(");

	strcpy(p_wordlist[30].name,")");

	strcpy(p_wordlist[31].name,",");

	strcpy(p_wordlist[32].name,";");

	strcpy(p_wordlist[33].name,".");

	strcpy(p_wordlist[34].name,"\n");
	
	for(i=0;i<35;i++)
		{
			p_wordlist[i].type=i+1;
			
		}

	DoubleOperand[0]=':';
	DoubleOperand[1]='<';
	DoubleOperand[2]='>';
}
void Retract()		//回退一个字符
{
	word_count--;
	backfront(&bufferqueue);
}
char getChar(FILE *fp)		//从缓冲区内读取一个字符
{
	word_count++;
	return ReadBuffer(fp);
}
void trim_bc(char *ch,FILE *fp)		//清除空白字符
{

	if(*ch==' ' || *ch=='\t')
	{
		if(*ch=='\t') word_count+=7;
		while(((*ch=getChar(fp))==' ')||*ch=='\t')
		{
			if(*ch=='\t')
				word_count+=7;
		}
	}
	/*
	else if(*ch=='\t')
	{
		
		word_count+=7;
		while((*ch=getChar(fp))=='\t')
			word_count+=7;
	}
	*/
}
int lookupwordlist(char *word)		//在单词编码表中查找关键字或操作符
{
	int loop_i;
	for(loop_i=0;loop_i<wordCount;loop_i++)
	{
		if(strcmp(word,(p_wordlist+loop_i)->name)==0)
			return (p_wordlist+loop_i)->type;
	}
	return 0;
}
int isLetter(char ch)
{
	if((ch>=65 && ch<=90) || (ch>=97 && ch <=122))
		return 1;
	else
		return 0;
}
int isDigit(char ch)
{
	if(ch>=48 && ch<=57)
		return 1;
	else
		return 0;
	
}
int isdoubleop(char ch)		//是否为两个字符操作符的首符,如:=中的:,<>中的<,>=中的>
{
	int loop_i;

	for(loop_i=0;loop_i<doubleop_count;loop_i++)
	{
		if(*(DoubleOperand+loop_i)==ch)
			return 1;
	}
	return 0;
}
int lookupoperand(char ch)		//查找单个字符的操作符
{
	char tmp[2]={ch,'\0'};
	return lookupwordlist(tmp);
}
void Concat(char ch,char *str)		//连接字符串
{
	int len=strlen(str);
	*(str+len)=ch;
}

void out_screen_pause(char *str,int code)		
{
	static int screen_count=1;
	if(screen_count>19)
	{
		printf("按任意键继续...");
		getch();

		clrscr();		//此函数最终调用WINAPI实现清除Console的屏幕

		screen_count=0;
	}

	printf("{%s,%d}\n",str,code);
	screen_count++;

}
void outword(char *str,int code,FILE *fp)		//输出单词
{
	static OUT_WORD_ITEM out_item;		//定义为static,一是可以用默认值初始化char[],二是此函数会被多次调用,static可以只分配一次空间
	

	strcpy(out_item.name,str);
	out_item.type=code;

	fwrite(&out_item,sizeof(OUT_WORD_ITEM),1,fp);
	
	out_screen_pause(str,code);
}
void error_screen(char *msg,char ch)
{
	printf(msg,ch);
	printf("行:%d, 列:%d\n",line_count,word_count);	
}
void error(char *msg,char ch)		//出错处理
{
	error_screen(msg,ch);
}
void scan(FILE *fp,FILE *fp_out)		//拼读一个单词
{	
	char strToken[33]="";
	char ch=getChar(fp);
	int code;
	trim_bc(&ch,fp);
	if(isLetter(ch))		//字母开头
	{
		while(isLetter(ch) || isDigit(ch))
		{
			Concat(ch,strToken);
			ch=getChar(fp);
		}
		if(ch!=0)		//如果读出来的字符为0,则说明缓冲区为空并且文件已经结束了
		{
			Retract();
			code=lookupwordlist(strToken);

			if(code!=0)		
			{
				outword(strToken,code,fp_out);
			}
			else
			{
				code=code_ident;
				outword(strToken,code,fp_out);
			}
		}
	}
	else if(isDigit(ch))	//数字开头
	{
		while(isDigit(ch))
		{
			Concat(ch,strToken);
			ch=getChar(fp);
		}
		if(ch!=0)
		{
			Retract();
			outword(strToken,code_const,fp_out);
		}
	}
	else if(doubleop_count!=0 && isdoubleop(ch))	
	{
		char second;
		Concat(ch,strToken);
		second=getChar(fp);
		if(ch!=0)
		{
			Concat(second,strToken);
			if(code=lookupwordlist(strToken))
			{
				outword(strToken,code,fp_out);
			}
			else if(code==lookupoperand(ch))
			{
				char tmp[2]={ch,'\0'};
				outword(tmp,code,fp_out);
				Retract();
			}
			else
			{
				//error
				error("错误:遇到非法运算符 \"%c\"\n",ch);
				Retract();
			}
		}
	}
	else if(code=lookupoperand(ch))
	{
		char tmp[2]={ch,'\0'};
		outword(tmp,code,fp_out);
	}
	else if(ch==13)		//对回车换行进行特别处理
	{
		
		char lf=getChar(fp);
		if(ch!=0)
		{
			line_count++;
			word_count=0;
			if(lf==10)
			{
				outword("newline",code_crlf,fp_out);
			}
			else
			{
				Retract();
				outword("newline",code_crlf,fp_out);
			}
		}
	}
	else
	{
		//error
		error("错误:错误的字符 \"%c\"\n",ch);
	}

}
void lexsan(int count, char **vars)
{
	char em;
	int f_eof;
	printf("\n");

    if(checkOpenFiles(count,vars)!=0)
		return;

	initiate(fp_wordList);
//	fclose(fp_wordList);

	LoadFileToBuffer(fp_source);

	em=BufferEmpty();
	f_eof=feof(fp_source);
	while(em!=1 || f_eof!=16)
	{
		scan(fp_source,fp_output);
		em=BufferEmpty();
		f_eof=feof(fp_source);
	}
	printf("分析完成.\n");
	
	//关闭打开的文件指针
	fclose(fp_source);
	fclose(fp_output);

	//关闭已经动态分配内存空间的指针
	if(malloc_DO==1)
		free(DoubleOperand);
	if(malloc_WL==1)
		free(p_wordlist);
}

⌨️ 快捷键说明

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