www.pudn.com > WordParser.rar > checkOpenFiles.c


/* Note:Your choice is C IDE */ 
#include "stdio.h"   
#include "string.h" 
#include "malloc.h" 
#include "my_conio.h" 
//全局变量定义 
FILE *fp_source;//源文件 
FILE *fp_output;//输出文件 
 
char DoubleOperand[3];//长度为2的运算符的第一个字符集合 
int wordCount=35;//单词编码个数 
int doubleop_count=3; 
int code_ident=17;//标示符 
int code_const=18;//常数 
int code_crlf=35;//回车 
int line_count=1;//行计数器 
int word_count=0;//字符计数器 
 
typedef struct  //单词编码数据结构 
{ 
	char name[20]; 
	int type; 
}WORDITEM; 
 
typedef struct //输出项数据结构 
{ 
	char name[50]; 
	int type; 
}OUTITEM; 
 
WORDITEM p_wordlist[35];  //定义单词编码数组 
#define BUFFERSIZE 100 
 
typedef struct   //缓冲队列数据结构 
{ 
		char data[BUFFERSIZE]; 
		int front,rear; 
}BUFFERQUEUE; 
 
BUFFERQUEUE bufferqueue; 
 
int empty(BUFFERQUEUE *bq)   //判空 
{ 
	if(bq->rear==bq->front) 
		return 1; 
	else 
		return 0; 
} 
 
 
int enqueue(BUFFERQUEUE *bq,char x)		//入队 
{ 
	int r; 
	if(bq->front==(bq->rear+1)%BUFFERSIZE) 
	{ 
		r=0; 
	} 
	else 
	{ 
		bq->rear=(bq->rear+1)%BUFFERSIZE; 
		(bq->data)[bq->rear]=x; 
		r=1; 
	} 
	return r; 
} 
 
char dequeue(BUFFERQUEUE *bq)			//出队 
{ 
	char v; 
	if(empty(bq)) 
	{ 
		v=NULL; 
	} 
	else 
	{ 
		bq->front=(bq->front+1)%BUFFERSIZE; 
		v=(bq->data)[bq->front]; 
	} 
	return v; 
} 
 
void LoadFileToBuffer(FILE *fp)	//加载文件内容至缓冲队列 
{ 
	char readchar; 
	int eof_f; 
	eof_f=feof(fp); 
	while(eof_f!=16) 
	{ 
		fread(&readchar,sizeof(char),1,fp); 
		if(enqueue(&bufferqueue,readchar)==0) 
		{ 
			fseek(fp,-1,1);		//回退一个字符 
			break; 
		}	 
		eof_f=feof(fp); 
 
		//发现每次文件结尾处的缓冲队列总是多读入一个相同的字符 
		if(eof_f==16) 
		{ 
			if(bufferqueue.rear!=0) 
				bufferqueue.rear-=1; 
			else 
				bufferqueue.rear=BUFFERSIZE-1; 
		} 
	} 
 
	 
	 
} 
 
char ReadBuffer(FILE *fp)	//取缓冲队列中的一个字符 
{ 
	if(empty(&bufferqueue)) 
	{ 
		LoadFileToBuffer(fp); 
	} 
	 
	return dequeue(&bufferqueue); 
} 
 
void backfront(BUFFERQUEUE *bq)		//回退操作 
{ 
	//if(empty(&bufferqueue)!=1) 
	//{ 
		if(bq->front!=0) 
			bq->front-=1; 
		else 
			bq->front=BUFFERSIZE-1; 
	//} 
} 
 
int BufferEmpty() 
{ 
	return empty(&bufferqueue); 
} 
 
//打开文件指针 
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; 
		} 
		return 0; 
	} 
} 
//初始化 
void initiate() 
{ 
	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; 
		} 
	} 
} 
 
int lookupwordlist(char *word)		//在单词编码表中查找关键字或操作符 
{ 
	int loop_i; 
	for(loop_i=0;loop_iname)==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_i19) 
	{ 
		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 OUTITEM out_item;		//定义为static,一是可以用默认值初始化char[],二是此函数会被多次调用,static可以只分配一次空间 
	 
 
	strcpy(out_item.name,str); 
	out_item.type=code; 
 
	fwrite(&out_item,sizeof(OUTITEM),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(); 
//	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"); 
	getchar(); 
	 
	//关闭打开的文件指针 
	fclose(fp_source); 
	fclose(fp_output); 
 
} 
//#include "BuildWordListFile.h" 
 
main(int count,char** vars)////////主调用函数 
{	 
	lexsan(count,vars); 
	 
}