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

📄 cifa.cpp

📁 编译原理的词法分析程序
💻 CPP
字号:
/////////////////////////////////处理空格问题如 int a;int b;处理数值问题,整数,小数等;处理读入读出问题,文件
// ;处理报错、纠错问题;处理格式类问题;


#include<iostream>
#include<fstream>
#include<string>
#include<cmath>
#include<iomanip>
using namespace std;


bool In_compute(char a);
 
bool In_limit(char a);
 
bool In_number(char a);
 
bool In_ID(char a);

bool In_keywords(string a);

double ChangeChar(string aaa,int i);  //把数字字符转换为数值
 
int main()
{
	
    ifstream infile("a.txt",ios::in);//
	if(!infile)
	{
		cerr<<"open error!"<<endl;
		exit(1);
	}
	char  input_char [200];
    int i=0;
    string input_string;
	do
	{
	infile.getline(input_char,200);
	cout<<input_char<<endl;
	input_string=input_string+input_char;
	}while (!infile.eof());
	i=input_string.size();

	///////////////////////////////除去空符
	        
    int *type=new int[i];//定义运算符整型数组
    for(int j=0;j<i;j++)
    {
      if(In_compute(input_string[j])) type[j]=4;//运算符定为类型4
      else if(In_limit(input_string[j]))  type[j]=5;//界符定为类型5 
      else if('0'<=input_string[j]&&input_string[j]<='9')//若该符是无符号数,定为类型3
	  {
		  type[j]=3;
		  j++;
		  while (In_number(input_string[j])) 
		  {
			  type[j]=3;
			  j++;
		  }
		  j--;
	  }
      else if(In_ID(input_string[j])&& input_string[j]>'9')//标识符和关键字先都作为标识符处理,定为2和1,下划线或字母开头   
      {
		  type[j]=2;
		  j++;
          while (In_ID(input_string[j]))
		  {
			  type[j]=2;
			  j++;
		  }
		  j--;  
	  }
	  
	  else if(input_string[j]==39)// 单引号  常量类型6           
	  {
             type[j]=6;
			 j++;
			 type[j]=6;
			 j++;
			 type[j]=6;
	  }
	  else if(input_string[j]=='"')//双引号  常量类型7
	  {
		     type[j]=7;
			 int k=j;
			 j++;
             while(input_string[j]!='"')
			 {
				 j++;
			 }
             for(;k<=j;k++)
			 {
                 type[k]=7;
			 }
	  }
	  else if(input_string[j]==' '||input_string[j]=='\n')//注意' '(一个空字符)不同于'\0'(一个结束标志)
	  {
		  type[j]=0;
	  }
	  else cout<<"ERROR"<<j+1;/////////////////////////////////////////?????????????
	}
 /////将标识符中的关键字部分提取出来
    string *a=new string[i];
	int k=0;//记录截取的单词个数
	int *StringType=new int[i];
	for(j=0;j<i;j++)
   {
	   switch (type[j])
	   {

	   
	   case 4:         //运算符定为类型4
		          while(type[j]==4)
				  {
		            a[k]=a[k]+input_string[j];
		            j++;
				  }
				  StringType[k]=4;
				  break;
	   case 2:        //
	             while(type[j]==2)
				 {
		            a[k]=a[k]+input_string[j];
		            j++;
				 }
				 if(In_keywords(a[k])) 
                 StringType[k]=1;     //关键字类型1
				 else StringType[k]=2;
				 break;
	   case 3:         //常数
                 while(type[j]==3)
				 {
		            a[k]=a[k]+input_string[j];
		            j++;
				 }
				 StringType[k]=3;
				 break;

       case 6:         //字符常量
                  j++;//越过首‘
		          a[k]=a[k]+input_string[j];
		          j++;//越过尾’
				  j++; //下一个
				 
				 StringType[k]=6;
				 break;

      case 7:         //字符串常量
		         j++;//越过首“
                 while(type[j]==7&&input_string[j]!='"')
				 {
		            a[k]=a[k]+input_string[j];
		            j++;
				 }
				 j++;//下一个
				 StringType[k]=7;
				 break;

	   
	   case 5:   //界符定为类型5
                 a[k]=a[k]+input_string[j];
		         StringType[k]=5;
				 j++;
				 break;
	   default:  while(type[j]==0)//遇上空格时
       	         {
					 j++;
				 } 
		         k--;
	   }
	   j--;
	   k++;
        
   }

   double *num_value=new double[k];
   for(int l=0;l<k;l++)
   {
      if(StringType[l]==3)
	  {
		  int m=a[l].size();
		  num_value[l]=ChangeChar(a[l],m); 
	  }
   }
	  
   
   cout<<" ****************总文件***********"<<endl; 
   cout<<setw(20)<<"位置"<<setw(20)<<"单词"<<setw(20)<<"类型"<<endl;
   for(l=0;StringType[k]!=0&&l<k;l++)
   {
	   switch(StringType[l])
	   {
	   case 1:cout<<setw(20)<<l+1<<setw(20)<<a[l]<<setw(20)<<StringType[l]<<endl;break;
       case 2:cout<<setw(20)<<l+1<<setw(20)<<a[l]<<setw(20)<<StringType[l]<<endl;break;
       case 3:cout<<setw(20)<<l+1<<setw(20)<<num_value[l]<<setw(20)<<StringType[l]<<endl;break; //常数
       case 4:cout<<setw(20)<<l+1<<setw(20)<<a[l]<<setw(20)<<StringType[l]<<endl;break;
       case 5:cout<<setw(20)<<l+1<<setw(20)<<a[l]<<setw(20)<<StringType[l]<<endl;break;
       case 6:cout<<setw(20)<<l+1<<setw(20)<<a[l]<<setw(20)<<StringType[l]<<endl;break;
	   case 7:cout<<setw(20)<<l+1<<setw(20)<<a[l]<<setw(20)<<StringType[l]<<endl;break;
	   }
   }

   ofstream outfile;
   outfile.open("total.txt");
   outfile<<setw(20)<<"位置"<<setw(20)<<"单词"<<setw(20)<<"类型"<<endl;
   for(l=0;StringType[k]!=0&&l<k;l++)
   {
	   switch(StringType[l])
	   {
	   case 1:outfile<<setw(20)<<l+1<<setw(20)<<a[l]<<setw(20)<<StringType[l]<<endl;break;
       case 2:outfile<<setw(20)<<l+1<<setw(20)<<a[l]<<setw(20)<<StringType[l]<<endl;break;
       case 3:outfile<<setw(20)<<l+1<<setw(20)<<num_value[l]<<setw(20)<<StringType[l]<<endl;break; //常数
       case 4:outfile<<setw(20)<<l+1<<setw(20)<<a[l]<<setw(20)<<StringType[l]<<endl;break;
       case 5:outfile<<setw(20)<<l+1<<setw(20)<<a[l]<<setw(20)<<StringType[l]<<endl;break;
       case 6:outfile<<setw(20)<<l+1<<setw(20)<<a[l]<<setw(20)<<StringType[l]<<endl;break;
	   case 7:outfile<<setw(20)<<l+1<<setw(20)<<a[l]<<setw(20)<<StringType[l]<<endl;break;
	   }
   }
   outfile.close();



   cout<<" ****************1.关键字***********"<<endl; 
   outfile.open("keyword.txt");
   outfile<<setw(20)<<"位置"<<setw(20)<<"关键字"<<endl;
   for(l=0;StringType[k]!=0&&l<k;l++)
   {
	   if(StringType[l]==1)
	   {   
		   
		   outfile<<setw(20)<<l+1<<setw(20)<<a[l]<<endl;
		   cout<<a[l]<<endl;
	   }
   }
   outfile.close();

   cout<<" ****************2.标识符***********"<<endl;    
   outfile.open("ID.txt");
   outfile<<setw(20)<<"位置"<<setw(20)<<"标识符"<<endl;
   for(l=0;StringType[k]!=0&&l<k;l++)
   {
	   if(StringType[l]==2)
		{   
		   
		   outfile<<setw(20)<<l+1<<setw(20)<<a[l]<<endl;
		   cout<<a[l]<<endl;
	   }	   
   }
   outfile.close();
   
   
   cout<<"  ****************3.常数***********"<<endl; 
   outfile.open("const number.txt");
   outfile<<setw(20)<<"位置"<<setw(20)<<"常数"<<endl;
   for(l=0;StringType[k]!=0&&l<k;l++)
   {
	   if(StringType[l]==3)
	   {   
		   
		   outfile<<setw(20)<<l+1<<setw(20)<<num_value[l]<<endl; 
		   cout<<num_value[l]<<endl;
	   }
		  
   }
   outfile.close();


   cout<<"  ****************4.运算符***********"<<endl;   
   outfile.open("compute sign.txt");
   outfile<<setw(20)<<"位置"<<setw(20)<<"运算符"<<endl;
   for(l=0;StringType[k]!=0&&l<k;l++)
   {
	   if(StringType[l]==4)
	   {   
		   
		   outfile<<setw(20)<<l+1<<setw(20)<<a[l]<<endl; 
		   cout<<a[l]<<endl;
	   }
   
   }
    outfile.close();

   cout<<" ****************5.界符  ***********"<<endl;  
    outfile.open("boundry sign.txt");
   outfile<<setw(20)<<"位置"<<setw(20)<<"界符"<<endl;
   for(l=0;StringType[k]!=0&&l<k;l++)
	{
	   if(StringType[l]==5)
		 {   
		   
		   outfile<<setw(20)<<l+1<<setw(20)<<a[l]<<endl; 
		   cout<<a[l]<<endl;
	   }
	} 
	 outfile.close();


   cout<<" ****************6.单字符 ***********"<<endl;  
   outfile.open("char sign.txt");
   outfile<<setw(20)<<"位置"<<setw(20)<<"单字符"<<endl;
   for(l=0;StringType[k]!=0&&l<k;l++)
	{
	   if(StringType[l]==6)
	   {   
		 
		   outfile<<setw(20)<<l+1<<setw(20)<<a[l]<<endl; 
		   cout<<a[l]<<endl;
	   }
	}  
    outfile.close();


    cout<<" ****************7.字符串***********"<<endl;  
    outfile.open("string sign.txt");
    outfile<<setw(20)<<"位置"<<setw(20)<<"字符串"<<endl;
    for(l=0;StringType[k]!=0&&l<k;l++)
	{
	   if(StringType[l]==7)
	   {   
		   
		   outfile<<setw(20)<<l+1<<setw(20)<<a[l]<<endl; 
		   cout<<a[l]<<endl;
	   }
	}
	 outfile.close();

	delete []type;
	delete []a;
    delete []num_value;
    delete []StringType;
 return 0;
}

bool In_compute(char a)
{
	char compute[11]={'+','-','*','/','=','%','<','>','!','|','&'}; 
	for(int i=0;i<11;i++)
	{
		if (a==compute[i])return true;
	}
	return false;
}
bool In_limit(char a)
{
	char limit[11]={';','{','(',')',',','?',':','}','#','[',']'}; 
	for(int i=0;i<11;i++)
	{
		if (a== limit[i])return true;
	}
	return false; 
}
bool In_number(char a)
{
	char number[]={'0','1','2','3','4','5','6','7','8','9','e','.'}; 
	if (a>='0'&&a<='9')return true;
else if(a=='e'||a=='.')return true;
else return false;
}
bool In_ID(char a)
{
    	if (a>='0'&&a<='9')return true;
		if(a>='a'&&a<='z')return true;
		if(a>='A'&&a<='Z')return true;
		if(a=='_')return true;
        return false;
}

bool In_keywords(string a)
{
  string keywords[65]=
  {

     "asm",      "auto",         "bad_cast",     "bad_typeid", 
     "bool",     "break",        "case",         "catch", 
     "char",     "class",        "const",        "const_cast", 
     "continue", "default",      "delete",       "do", 
     "double",   "dynamic_cast", "else",         "enum", 
     "except",   "explicit",     "extern",       "false", 
      "finally",  "float",        "for",          "friend", 
     "goto",     "if",           "inline",       "int", 
     "long",     "mutable",      "namespace",    "new", 
     "operator", "private",      "protected",    "public", 
     "register", "reinterpret_cast",     "return",   "short", 
     "signed",   "sizeof",       "static",       "static_cast", 
     "struct",   "switch",       "template",     "this", 
     "throw",    "true",         "try",          "typedef",
     "typeid",   "typename",     "union",        "unsigned",
     "using",    "virtual",      "void",         "volatile", 
     "while"
  };
	for(int i=0;i<65;i++)
		if(a==keywords[i])return true;
	return false;
}


double ChangeChar(string aaa ,int i )  //把数字字符转换为数值
{
	int j,k,l,p;
	double n=0.0,m=0.0;
	for(j=0;j<i;j++)                    //对小数点进行定位,无小数点返回-1
	{
		if(aaa[j]=='.') {k=j; break;}
		else k=-1;
	}
	for(j=0;j<i;j++)               //对e定位,无e返回-1
	{
		if(aaa[j]=='e') {l=j;break;}
		else l=-1;
	}
	if(k==-1&&l==-1)                       //整数情况转数值    
	{
		for(p=0;p<i;p++)
		{
			m=(aaa[p]-'0')*pow(10,i-1-p);
			n=n+m;
		}
	}
	else if(k!=-1&&l==-1)                            //小数情况转数值,不含e
	{
		for(p=0;p<k;p++)            //小数的整数部分
		{
			m=(aaa[p]-'0')*pow(10,k-1-p);
            n=n+m;
		}
		for(p=k+1;p<i;p++)         //小数的小数部分
		{
			m=(aaa[p]-'0')*pow(10,k-p);
			n=n+m;
		}
	}
	else 
	{
        for(p=0;p<k;p++)            //小数的整数部分
		{
			m=(aaa[p]-'0')*pow(10,k-1-p);
            n=n+m;
		}
		for(p=k+1;p<l;p++)         //小数的小数部分
		{
			m=(aaa[p]-'0')*pow(10,k-p);
			n=n+m;
		}
		m=0;
		for(p=l+1;p<i;p++)
		{   
			m=m+(aaa[p]-'0')*pow(10,i-1-p);
		}
        n=n*pow(10,m);
	}
	return n;
}

⌨️ 快捷键说明

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