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

📄 cfmain.cpp

📁 一个能对C语言中的所有关键字以及运算符,界符进行识别,以种别值与单词符号的形式输出.
💻 CPP
字号:
/*****************************************************
 
词法分析程序:以文件形式输入源程序,文件输出单词符号

******************************************************/

#include<stdlib.h>
#include<stdio.h>
#include<string.h>

char *Key_Word[]={" ","auto","break","case","char","const","continue","default","do","double",
                 "else","enum","extern","float","for","goto","if","int","long","register",
                 "return","short","signed","sizeof","static","struct","switch","typedef",
                 "union","unsigned","void","volatile","while"};     /*C语言中全部的关键字,一共32个*/
char *Count_Boundary[]={" ","(",")","[","]","->",".","!","++","--","&","~",
                   "*","/","%","+","-","<<",">>","<","<=",">",">=","==","!=","&&","||",
                  "=","+=","-=","*=","/=",",",";","{","}","#","_","'"};/*运算符、界符*/

/*******************************************
 函数名:Initial()
 作用:  初始化函数
********************************************/
void Initial()
{             
 
    FILE *fp;
    int i;
    char c;
    fp=fopen("关键字.txt","w");
    for(i=1;i<=32;i++)
       fprintf(fp,"%s\n",Key_Word[i]);
    fclose(fp);               /*初始化关键字表,并将关键字写入该表*/
    fp=fopen("运算界符.txt","w");
    for(i=1;i<=38;i++)
       fprintf(fp,"%s\n",Count_Boundary[i]);
    c='"';
    fprintf(fp,"%c\n",c);
    fclose(fp);               /*初始化运算符、界符表,并将运算符、界符写入该表*/
    fp=fopen("标识符.txt","w");
    fclose(fp);               /*初始化标识符表*/
    fp=fopen("常数.txt","w");
    fclose(fp);               /*初始化常数表*/
    fp=fopen("Word_Analyse_List.txt","w");
    fclose(fp);               /*初始化输出文件*/
}


/*******************************************
 函数名:char *DecToBin(char *buf)
 作用: 十进制转二进制函数
********************************************/
char *DecToBin(char *buf)
{          
    int temp[20];
	char *binary;
	int value=0,i=0,j;
	for(i=0;buf[i]!='\0';i++)
		value=value*10+(buf[i]-48);       /*先将字符转化为十进制数*/
    if(value==0)
    {
		binary=(char *)malloc(2*sizeof(char));
		binary[0]='0';
		binary[1]='\0';
		return(binary);
	}
	i=0;
	while(value!=0)
    {
		temp[i++]=value%2;
		value/=2;
	}
	temp[i]='\0';
	binary=(char *)malloc((i+1)*sizeof(char));
	for(j=0;j<=i-1;j++)
       binary[j]=(char)(temp[i-j-1]+48);
    binary[i]='\0';
    return(binary);
}

/*******************************************
 函数名:int Word_Search(char *buf,int Type,int Command)
 作用:根据不同命令查表或造表函数
********************************************/
int Word_Search(char *buf,int Type,int Command)
{             
    int number=0;
    FILE *fp;
    char c;
    char temp[30];
    int i=0;
    switch(Type)
    {
        case 1: fp=fopen("关键字.txt","r");break;
        case 2: fp=fopen("标识符.txt","r");break;
        case 3: fp=fopen("常数.txt","r");  break;
        case 4: fp=fopen("运算界符.txt","r");
    }
    c=fgetc(fp);
    while(c!=EOF)
    {
        while(c!='\n')
        {
            temp[i++]=c;
            c=fgetc(fp);
        }
        temp[i]='\0';
        i=0;
        number++;
        if(strcmp(temp,buf)==0)
        {  
		    fclose(fp);
			return(number);        /*若找到,返回在相应表中的序号*/
        }
        else
           c=fgetc(fp);
     }
     if(Command==1)
     {   
	     fclose(fp); 
		 return(0);                /*找不到,当只需查表,返回0,否则还需造表*/
     }
     switch(Type)
     {
         case 1: fp=fopen("关键字.txt","a");break;
         case 2: fp=fopen("标识符.txt","a");break;
         case 3: fp=fopen("常数.txt","a");break;
         case 4: fp=fopen("运算界符.txt","a");
     }
     fprintf(fp,"%s\n",buf);
     fclose(fp);
     return(number+1);             /*造表时,将字符串添加到表尾并返回序号值*/
}

/*******************************************
函数名:void Num_Dispose(char *buffer)
作用:  数字串处理函数
********************************************/
void Num_Dispose(char *buffer)
{             
    FILE *fp;
	char *pointer;
	int result;
	pointer=DecToBin(buffer);
    result=Word_Search(pointer,3,2);       /*先查常数表,若找不到则造入常数表并返回序号值*/
    fp=fopen("Word_Analyse_List.txt","a");
	fprintf(fp,"%s\t\t\t\t\t\t43\n",buffer);
	fclose(fp);               /*写入输出文件*/
}

/*******************************************
函数名:void Char_Dispose(char *buffer)
作用:  字符串处理函数 
********************************************/
void Char_Dispose(char *buffer)
{                     
    FILE *fp;
    int result;
    result=Word_Search(buffer,1,1);                /*先查关键字表*/
    fp=fopen("Word_Analyse_List.txt","a");
    if(result!=0)
       fprintf(fp,"%s\t\t\t\t\t\t41\n",buffer);    /*若找到,写入输出文件*/
    else
    {
        result=Word_Search(buffer,2,2);           /*若找不到,则非关键字,查标识符表,还找不到则造入标识符表*/
        fprintf(fp,"%s\t\t\t\t\t\t42\n",buffer); /*若找到, 写入输出文件*/
    }                                
    fclose(fp);
}
/*******************************************
函数名:void Error_Dispose(char Error,int LineNum)
作用:  出错处理函数
********************************************/
void Error_Dispose(char Error,int LineNum)
{                 
    printf("\nOneError: %cline %d",Error,LineNum);    /*报告出错符号和所在行数*/
}
/*******************************************
函数名:void Word_Analyse()
作用:  逐个字符地扫描源程序
步骤:
1.打开需要进行词法分析的源程序"测试程序.txt"文本文件,如打开失败,显示错误信息.
2.先从源程序中读入一个字符进行判断.如果是字母或下划线则转向3,如果是数字则转向4,
如果是无用字符则转向5,如果是运算符或界符转向6,否则转向7.
3.继续读入字符,直到读到其它字符时调用字符串处理函数Char_Dispose.
4.继续读入字符,直到读到非数字时调用数字串处理函数Num_Dispose.
5.对如空格符,换行符,回车符,跳格符,注释中的内容等等剔除掉.
6.调用Word_Search函数在相应的表中查找该运算符或界符.
7.退出程序.  
********************************************/
void Word_Analyse()
{            
    FILE *fpin,*fpout;
    char ch;
    int i=0,line=1;
    int count,result,Error_Num=0;
	char array[32];
    char *word;
    if((fpin=fopen("测试程序.txt","r"))==NULL)
    {
        printf("Cannot open file");
        return;
    }
    ch=fgetc(fpin); 
    while(ch!=EOF)        /*按字符依次扫描源程序,直至结束*/
    {            
        i=0;
        if(((ch>='A')&&(ch<='Z'))||((ch>='a')&&(ch<='z'))||(ch=='_'))  /*以字母开头*/
        {         
            while(((ch>='A')&&(ch<='Z'))||((ch>='a')&&(ch<='z'))||(ch=='_')||((ch>='0')&&(ch<='9')))
            {
                array[i++]=ch;
                ch=fgetc(fpin);
            }
            word=(char *)malloc((i+1)*sizeof(char));
			memcpy(word,array,i);
			word[i]='\0';
            Char_Dispose(word);
            if(ch!=EOF)
			   fseek(fpin,-1L,SEEK_CUR);
        }
        else if(ch>='0'&&ch<='9')        /*以数字开头*/
        {   
            while(ch>='0'&&ch<='9')
            {
                array[i++]=ch;
                ch=fgetc(fpin);
            }
            word=(char *)malloc((i+1)*sizeof(char));
			memcpy(word,array,i);
			word[i]='\0';
            Num_Dispose(word);
            if(ch!=EOF)
			   fseek(fpin,-1L,SEEK_CUR);
        }

		/*进行预处理,跳过无用的字符*/
        else if((ch==' ')||(ch=='\t'))    
			;                  /*消除空格符和水平制表符*/
		else if(ch=='\n')
			line++;            /*消除回车并记录行数*/
		else if(ch=='/')
        {                      /*消除注释*/
			ch=fgetc(fpin);
			if(ch=='=')
			{                  /*判断是否为‘/=’符号*/
				fpout=fopen("Word_Analyse_List.txt","a");
				fprintf(fpout,"/=\t\t\t\t\t\t32\n");
                fclose(fpout);
			}
			else if(ch!='*')
            {                 /*若为除号写入输出文件*/
                fpout=fopen("Word_Analyse_List.txt","a");
				fprintf(fpout,"/\t\t\t\t\t\t13\n");
                fclose(fpout);
				fseek(fpin,-1L,SEEK_CUR);
			}
			else if(ch=='*')
			{              /*若为注释的开始,消除包含在里面的所有字符*/
				count=0;
				ch=fgetc(fpin);
				while(count!=2)
                {          /*当扫描到‘*’且紧接着下一个字符为‘/’才是注释的结束*/
					count=0;
					while(ch!='*')
						ch=fgetc(fpin);
					count++;
					ch=fgetc(fpin);
					if(ch=='/')
						count++;
					else
						ch=fgetc(fpin);
				}
			}
		}
		else if(ch=='"')   /*消除包含在双引号中的字符串常量*/
		{              
			fpout=fopen("Word_Analyse_List.txt","a");
			fprintf(fpout,"%c\t\t\t\t\t\t37\n",ch);
			ch=fgetc(fpin);
			while(ch!='"')
				ch=fgetc(fpin);
            fprintf(fpout,"%c\t\t\t\t\t\t37\n",ch);
			fclose(fpout);
		}
		else
        {         /*首字符为其它字符,即运算符、界符或非法字符*/
            array[0]=ch;
            ch=fgetc(fpin);       /*再读入下一个字符,判断是否为双字符运算符、界符*/
            if(ch!=EOF)
            {           /*若该字符非文件结束符*/
                array[1]=ch;
				word=(char *)malloc(3*sizeof(char));
				memcpy(word,array,2);
				word[2]='\0';
                result=Word_Search(word,4,1);      /*先检索是否为双字符运算符、界符*/
				if(result==0)
				{                           /*若不是*/
                    word=(char *)malloc(2*sizeof(char));
					memcpy(word,array,1);
					word[1]='\0';
					result=Word_Search(word,4,1);      /*检索是否为单字符运算符、界符*/
					if(result==0)
                    {                           /*若还不是,则为非法字符*/
						Error_Dispose(array[0],line);
						Error_Num++;
						fseek(fpin,-1L,SEEK_CUR);
                    }
                    else
					{     /*若为单字符运算符、界符,写入输出文件并将扫描文件指针回退一个字符*/
						fpout=fopen("Word_Analyse_List.txt","a");
						fprintf(fpout,"%s\t\t\t\t\t\t%d\t\n",word,result);
						fclose(fpout);
						fseek(fpin,-1L,SEEK_CUR);
					}
				}
                else
				{             /*若为双字符运算符、界符,写入输出文件*/
					fpout=fopen("Word_Analyse_List.txt","a");
					fprintf(fpout,"%s\t\t\t\t\t\t%d\n",word,result);
					fclose(fpout);
				}
            }
            else
			{               /*若读入的下一个字符为文件结束符*/
				word=(char *)malloc(2*sizeof(char));
				memcpy(word,array,1);
				word[1]='\0';
				result=Word_Search(word,4,1);       /*只考虑是否为单字符运算符、界符*/
				if(result==0)                /*若不是,转出错处理*/
					Error_Dispose(array[0],line);
				else
				{                            /*若是,写输出文件*/
					fpout=fopen("Word_Analyse_List.txt","a");
					fprintf(fpout,"%s\t\t\t\t\t\t%d\n",word,result);
					fclose(fpout);
				}
			}
        }
        ch=fgetc(fpin); 
    }
    fclose(fpin);
	printf("There are %d Error(s).\n",Error_Num);         /*报告错误字符个数*/
}

/*******************************************
 main函数
********************************************/
int main()
{           
    FILE *fp;
    Initial();            /*初始化*/
	fp=fopen("Word_Analyse_List.txt","w");
	fprintf(fp,"单词符号串\t\t\t\t       种别编码值\n");
	fclose(fp);
	Word_Analyse();       /*扫描源程序*/
    return 1;
}  

⌨️ 快捷键说明

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