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

📄 词法分析器.cpp

📁 c语言的此法分析器
💻 CPP
字号:
#include"stdio.h"
#include"stdlib.h"
#include"iostream.h"
#include"iomanip.h"
#include"fstream.h"
#include"string.h"

#define  KEYWORD_NUM 34
#define  OPERATES_NUM1  7
#define  OPERATES_NUM2  6
#define  LIMIT_NUM    8


int In_KeyWords(char * str,char * string[KEYWORD_NUM]);
int In_Limit_Words(char str, char string[LIMIT_NUM]);
int In_Operates1(char str, char string1[OPERATES_NUM1]);
int In_Operates2(char *str , char *string2[OPERATES_NUM2]);

void main()
{
 FILE *fp;                               //记录读文件指针
 char FileName[20]; 
 char ch ,ch_add ;                        //ch记录当前输入的字符,ch_add记录当前输入的前一个字符(因为最长的运算符和界符占两个字符)
 int count=0;
 char  tempstr[81];                         //记录当前读入的字符串
 
 int flag;                               //标志它是不是关键字
 int notflag1=0 ;                           //标志它目前是不是已经出现了非法字符
 int notflag2=0;
 



 char * Keywords[KEYWORD_NUM]={"auto", "break", "case","char",       //关键子的记号为1
                     "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","printf","scanf"};                       // 定义关键字字符串数组 

char  Operates1[OPERATES_NUM1]={'+', '-', '*', '/',  '>','<',      //运算符的记号为2
                                '='};
char * Operates2[OPERATES_NUM2]={"<=",">=","==","!=","++","--"};

char  Limit_Words[LIMIT_NUM]={';', ',', '(', ')', '[', ']',       //界符的记号为3
                               '{', '}'};                            //至于注释符/*则直接在程序中体现
							                                        
                                                                   //标识符的记号为4 ,常数的标识符为5

 


	cout<<"请输入你要分析的文件的名称:";
	cin>>FileName;
	cout<<endl<<endl;

   if((fp=fopen(FileName ,"r"))==NULL)
     {
       cout<<endl<<"文件打开失败!"<<endl;
	   exit(0);                           //打开测试文件
     }
  
  ch=fgetc(fp);
  while(ch!=EOF)
    { 
	   while(ch==' ')
	   {
	    ch=fgetc(fp);
	   }
	   
	   ch_add=ch;
	   ch=fgetc(fp);
	   if(In_Limit_Words(ch_add,Limit_Words))           //判断第一个字符就是不是界符
	    {
		 cout<<endl<<"< "<<ch_add;          
		 cout<<"  ,  界符 >"<<endl;
		}
      
	  
	   if((In_Operates1(ch_add,Operates1))&&(ch!='*')&&(ch!='/'))    //判断第一个字符就是不是操作符(此时需考虑注释符号)
	    {
		 cout<<endl<<"< "<<ch_add ;          
		 cout<<"  ,  运算符 >"<<endl;
		}
	  
	  
	   if(ch_add=='/'&& ch=='*')                 //略去注释部分
	    {
			do
			{
			ch_add=ch;
			ch=fgetc(fp);
		 
			if(ch_add=='/'&& ch=='*')
			cout<<endl<<"错误!注释不能嵌套!!"<<endl;
		 
			}
			while(!(ch_add=='*'&& ch=='/'));
		}
	   
	   
   if(In_Limit_Words(ch_add,Limit_Words)||(In_Operates1(ch_add,Operates1))&&(ch!='*')&&(ch!='/'))
   {
      fseek(fp,-1,1);           //将文件读指针定位于第一个不是空格,界符,运算符的字符
	   fgets(tempstr,2,fp); 
   }

	 else  
	 {
		 fseek(fp,-2,1);           //将文件读指针定位于第一个不是空格的字符
	    fgets(tempstr,3,fp);    //从当前位置读入两个有效字符,第三个字符读入的是“\0”
	 }

	   if(In_Operates2(tempstr,Operates2))
	   {
		 cout<<endl<<"< "<<tempstr ;          
		 cout<<"  ,  运算符 >"<<endl;
	   }
	                            //注意,此时文件的读指针位于第三个字符上
	   
       if(In_Limit_Words(ch_add,Limit_Words)||(In_Operates1(ch_add,Operates1))&&(ch!='*')&&(ch!='/'))
   {
      fseek(fp,-1,1);           //将文件读指针定位于第一个不是空格,界符,运算符的字符
	  // fgets(tempstr,3,fp); 
   }

	 else  
	 {
		 fseek(fp,-2,1);           //将文件读指针定位于第一个不是空格的字符
	    //fgets(tempstr,3,fp);    //从当前位置读入两个有效字符,第三个字符读入的是“\0”
	 }

	  // else fseek(fp,-2,1);     //下面重新将文件读指针定位于第一个不是空格的字符
	  
	   ch=fgetc(fp);
	   count=1;
      
	   if((ch>64&&ch<91)||(ch>96&&ch<123)||ch=='_')  //标识符ID的可以使用的合法字符是字母和下划线

        {   
			 notflag1=0;
			//ch=fgetc(fp);
			
				while(ch!=' '&& ch!='!' &&(!In_Operates1(ch,Operates1))&&(!In_Limit_Words(ch,Limit_Words)) )
				{
				if(!(ch>64&&ch<91)&&!(ch>96&&ch<123)&&ch!='_')
				notflag1=1;

				count++;
				ch=fgetc(fp);

				}
			 fseek(fp, (0-(count)),1);
			 fgets(tempstr,(count),fp);
			 
			 flag=In_KeyWords(tempstr,Keywords);
			 
				if(flag==0 && notflag1==0)                                  //如果不是关键字且 没有出现非法字符
				{
				cout<<endl<<"< "<<tempstr ;          
				cout<<"  ,  标识符 >"<<endl;
				}

				else if(notflag1==1) 
				{
				cout<<endl<<tempstr ;          
				cout<<"是非法字符串!"<<endl;
				}
		 
	    }

			
       if(ch>47&&ch<58)
	    {
		       notflag2=0;
		      // ch=fgetc(fp);

				while( ch!=' '&& ch!='!' &&(!In_Operates1(ch,Operates1))&&(!In_Limit_Words(ch,Limit_Words)))
				{
				
				if(ch<=47||ch>=58)
				notflag2=1;
				count++;
				ch=fgetc(fp);

				}
			 fseek(fp, (0-(count)),1);
			 fgets(tempstr,(count),fp);
			 
				if(notflag2==0)                                  //如果不是关键字
				{
				cout<<endl<<"< "<<tempstr ;          
				cout<<"  , 常数 >"<<endl;
				}

				else 
				{
				cout<<endl<<"< "<<tempstr ;          
				cout<<"是非法字符串!"<<endl;
				}
		  
		 }
	   ch=fgetc(fp);
    }
}
		                          
	   
int In_KeyWords(char * str,char * string[KEYWORD_NUM])	   
 {
   for(int i=0;i<KEYWORD_NUM;i++)
     {
	  if(!(strcmp(string[i],str)))
	    {
		 cout<<endl<<"< "<<str ;          
		 cout<<"  ,  关键字 >"<<endl;
		 return 1;
		}
	 }
   if(i>=KEYWORD_NUM)  return 0;
 }


int In_Limit_Words(char str, char string[LIMIT_NUM])
{
 for (int i=0;i<LIMIT_NUM;i++)
   {
    if ( str==string[i])
		{
		 return 1;
		 break;
		}
		
   }
  if(i>=LIMIT_NUM) 
 
	 return 0;
}
	   

int In_Operates1(char str, char string1 [OPERATES_NUM1])
{
 for (int i=0;i<OPERATES_NUM1;i++)
   {
    if (str==string1[i])
		{
		 return 1;
		 break;
		}
		
   }
  if(i>=OPERATES_NUM1) 
	 return 0;
}

int In_Operates2(char *str, char *string2[OPERATES_NUM2])
{
 for (int i=0;i<OPERATES_NUM2;i++)
   {
    if (!(strcmp(string2[i],str)))
		
		{
		 return 1;
		 break;
		}
		
   }
  if(i<=OPERATES_NUM2) 
	 return 0;
}

⌨️ 快捷键说明

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