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

📄 c语言词法分析.cpp

📁 C++ C 词法分析器
💻 CPP
字号:
//源代码文件: test.txt;
//分析结果存放文件: output.txt

#ifndef _GLOBAL_H 
#define _GLOBAL_H 
#include <stdio.h> 
#include <ctype.h> 
#include <string> 
using namespace std; 
#define MAX 6 //分析表的最大容量 
#define MAXBUF 255 

char ch =' ';// 存放读入当前的输入字符 
int lineno = 1;//程序行数 

struct entry{ 	
	const char *lexptr; //关键字表中的结构	
	int token; 	
}; 

struct entry symtable[MAX];//分析表 
static string str[] = {"main","if","else","for","void","int","printf"};//关键字 

#endif 


void init()//初始化符号表 
{ 	
	struct entry* p = symtable; 	
	int j=0; 	
	for(j=0;j<6;j++) 		
	{ 		
		p->lexptr=str[j].c_str(); 		
		p->token=j+3; 		
		p++; 		
	} 	
} 

//判断一个字符是否为数字 
bool IsDigit(char ch) 
{ 	
	return(ch>='0'&&ch<='9'); 	
} 


//判断一个字符是否确为字母 
bool IsAlpha(char ch) 
{ 	
	return (ch>='a'&&ch<='z'||ch>'A'&&ch<'Z'); 	
} 


/****************************************************************** 
功能:在关键字表中查找与arr相同的关键字 
找到就返回类别编码,否则返回0 	
*******************************************************************/ 
int FindOK(char* arr) 
{ 	
	for(int i=0;i<sizeof(symtable)/sizeof(symtable[0]);++i) 		
	{ 		
		if(!strcmp(symtable[i].lexptr,arr)) 			
		{ 			
			return symtable[i].token; 			
		} 		
	} 	
	return 0; 	
} 

/******************************************************************** 
以下为主分析函数 
从输入文件里面读,把分析结果写到输出文件中 
参数  fpin : 输入文件指针
fpout: 输出文件指针 	  
********************************************************************/ 
void parse(FILE* fpin,FILE* fpout) 
{ 	
	char arr[MAXBUF]; 	
	char line[MAXBUF]; 	
	int position = 0; 	
	int i=0; 	
	int j=0; 	
	bool begin = true; 	
	bool finished = false; 	
	while(!feof(fpin)) 		
	{ 	
		if(finished) 		
			break; 		
		if(begin) 			
		{ 			
			fgets(line, MAXBUF-1, fpin); //从程序中读入一行代码 			
			fprintf(fpout,"line %d:\n", lineno); 			
			begin = false; 			
			position = 0; 			
		} 		
		ch = line[position++];//把这行的一个字符赋给ch 		
		if( ch==' '||ch=='\t')//消去空格 			
			; 		
		else if(ch=='\n')//消去Enter 			
		{ 			
			lineno++; 			
			begin = true; 			
		}		
		else if(IsDigit(ch))//检查字符是否为数字 			
		{ 			
			while(IsDigit(ch)) //区分数字由单个字符还是多个字符构成 				
			{ 				
				arr[j] = ch; 				
				j++; 				
				ch = line[position++]; 				
			} 			
			position--; //文件指针后退一步 			
			char* temp1 =(char*)malloc(j+1); 			
			memcpy(temp1,arr,j); 			
			temp1[j] ='\0';//把数组里面的内容拷贝到外一个数组里面,因为定义的arr为255个字节, 			
			j=0; //实际上写不到那么多,所以只拷贝实际上有数据的 			
			//fprintf(fpout,"%s\t\t%d\n",temp1,2);//恢复初始状态,以备下次使用 			
			free(temp1);//释放内存 			
		} 		
		else if(IsAlpha(ch))//是字母开头的 			
		{ 			
			while(IsAlpha(ch)||IsDigit(ch)) 				
			{ 				
				arr[i] = ch; 				
				i++; 				
				//fscanf(fpin,"%c",&ch); 				
				ch = line[position++]; 				
			} 			
			//fseek(fpin,-1L,SEEK_CUR); 			
			position--; //文件指针后退一步 			
			char* temp = (char*)malloc(i+1); 			
			memcpy(temp,arr,i); 			
			temp[i] ='\0'; 		
			i=0; 			
			/*基本思想同处理数字的*/ 
			
			if(FindOK(temp))//查表 				
			{ 				
				fprintf(fpout,"%s\t%d\n",temp,FindOK(temp)); 				
			} 			
			else 				
			{ continue;			
			//fprintf(fpout,"%s\t%d\n",temp,1);//标示符号 			
			} 			
			free(temp); 			
		} 
		
		//以下为2字节的运算符号 		
		else if( ch==':') 		
		{ 			
			//fscanf(fpin,"%c",&ch); 			
			ch = line[position++]; 		
			if(ch=='=') 			
				fprintf(fpout,"%s\t%d\n",":=",20); 			
			else 			
				fprintf(fpout,"error in compileing %d lines unknown character %c \n",lineno,ch);//出错处理 			
		} 		
		else if(ch=='>') 			
		{ 			
			//fscanf(fpin,"%c",&ch); 			
			ch = line[position++]; 			
			if(ch=='=') 				
				fprintf(fpout,"%s\t%d\n",">=",16); 			
			else 				
				fprintf(fpout,">\t15\n"); 			
		} 		
		else if(ch=='<') 			
		{ 			
			//fscanf(fpin,"%c",&ch); 			
			ch = line[position++]; 			
			if(ch=='=') 				
			{fprintf(fpout,"<=\t18\n");} 			
			else if(ch=='>') 				
			{fprintf(fpout,"<>\t19");} 			
			else 				
			{fprintf(fpout,"<\t19\n");} 			
		} 		
		else { 			
			//以下为一个字节的运算符号			
			if(ch=='{') {fprintf(fpout,"{\t\t24\n");continue;}			
			if(ch=='}') {fprintf(fpout,"}\t\t25\n");continue;}			
			if(ch=='-') {fprintf(fpout,"-\t\t10\n");continue;} 			
			if(ch==';') {fprintf(fpout,";\t\t21\n");continue;} 			
			if(ch=='+') {fprintf(fpout,"+\t\t9\n");continue;} 			
			if(ch=='*') {fprintf(fpout,"*\t\t11\n");continue;} 			
			if(ch=='/') {fprintf(fpout,"/\t\t12\n");continue;} 			
			if(ch=='(') {fprintf(fpout,"(\t\t13\n");continue;} 			
			if(ch==')') {fprintf(fpout,")\t\t14\n");continue;} 			
			if(ch=='.') {fprintf(fpout,".\t\t22\n");continue;} 			
			if(ch==',') {fprintf(fpout,",\t\t23\n");continue;} 			
			if(ch=='#') break;//分析结束 			
			else continue; 			
		} 	
     } 
}

//主函数 
int main() 		
{ 		
	char filenamein[50],filenameout[50];		
	printf("************************************************\n");		
	printf("* C 语言子集词法分析程序 *\n");		
	printf("************************************************\n");		
	printf("请输入测试代码文件地址(例:c:\\test.txt): \n"); //注意代码中必须为双斜杠,而在输入时是单斜杠		
	scanf("%s",filenamein); 		
	printf("请输入输出目标文件地址(例:c:\\output.txt): \n"); 		
	scanf("%s",filenameout); 		
	FILE* fpin = fopen(filenamein,"r"); //定义源代码文件为只读		
	if(fpin==NULL)			
	{ 
		printf("不能打开代码文件!");//出错操作		 		
	    getchar(); 		
	    return 0; 		
	}		
	FILE* fpout = fopen(filenameout,"w");		
	if(fpout==NULL)			
	{ 
		printf("不能打开结果文件!");				
        getchar(); 		
	    return 0; 		
	}		
	init(); 		
	parse(fpin,fpout);//扫描需分析文件并输出分析结果 		
	fclose(fpin);//关闭源代码 		
	fclose(fpout); //关闭结果文件 	
	printf("OK..........\n"); 		
	getchar(); 		
	return 0; 
	
}

⌨️ 快捷键说明

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