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

📄 checkopenfiles.c

📁 为编译原理课程设计
💻 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_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 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);
	
}

⌨️ 快捷键说明

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