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

📄 lex.cpp

📁 C词法分析程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include<iostream>
#include<fstream>
#include<string>
#include<cmath>
using namespace std;
int colume=0;
int *ERROR=new int [100];
int error=0;
struct table
{
	string *pst;
	int size;
	int length;
};
struct tablenum
{
	double *pst;
	int size;
	int length;
};

bool Keyword(char c,string *KEYWORD,int KNLength,ifstream &infile,
			 table &table_key,table &table_ID,table &table_operator,table &table_delimiter);
bool Identify(char c,ifstream &infile,string &strtemp,table &table_ID,
			  table &table_operator,table &table_delimiter);
bool ConstN(char c,ifstream &infile,table &table_const);
bool ConstStr(char c,ifstream &infile,table &table_const);
bool ConstChar(char c,ifstream &infile,table &table_const);
bool ConstNum(char c,ifstream &infile,tablenum &table_const,table &table_operator,
			   table &delimiter);
bool Operator(char c,ifstream &infile,table &table_operator,table &table_delimiter);
bool Delimiter(char c,table &table_delimiter );
void Getword(table &table_sub,string stemp);
void Getnum(tablenum &table_sub,double temp);

int classfify(char c);
int classify_num(char c);

//输出控制函数
void Manager(table &table_key,table &table_ID,table &table_operator,
			 table &table_delimiter,table &table_const,tablenum &table_num);
void Outtenspace();
void ShowError(char &select1) ;
void ShowDelimiter(table &table_delimiter,char &select1) ;
void ShowOperator(table &table_operator,char &select1);
void ShowConst(table &table_const,tablenum &table_num,char &select1);
void ShowID(table &table_ID,char &select1);
void ShowKeywords(table &table_key,char &select1);

//写文件
void Outputfile(table & table_sub,char *p,int a);
void Outputfile(tablenum &table_num,char *p,int a);
void Outputfile(char *P);

int main()
{
  //读出关键字
  string KEYWORD[80];
  int KNLength=0;
  ifstream inf("KEYWORD.txt",ios::in);
  if(!inf){cout<<"error";exit(1);}
  int i=0;
  while(inf>>KEYWORD[i])
	  i++;
  KEYWORD[i]="-1";
  KNLength=i;
  inf.close();
  
  //初始化关键字表
  table table_key;
  table_key.pst=new string [50];
  table_key.size=50;
  table_key.length=0;

  //初始化标识符表
  table table_ID;
  table_ID.pst=new string [50];
  table_ID.length=0;
  table_ID.size=50;

  //初始化字符串常量字符表
  table table_const;
  table_const.pst=new string[50];
  table_const.length=0;
  table_const.size =50;

  //初始化数字常量字符表
  tablenum table_num;
  table_num.pst=new double[50];
  table_num.length=0;
  table_num.size=50;
  
  //运算符字符表
  table table_operator;
  table_operator.pst=new string [50];
  table_operator.length=0;
  table_operator.size =50;

 
 //界符字符表
  table table_delimiter;
  table_delimiter.pst=new string[100];
  table_delimiter.length =0;
  table_delimiter.size =100;

  
	ifstream infile("procedure.txt",ios::in);
    if(!infile){cout<<"error";exit(1);}
	char c;
	while(infile.get(c))
	{
		if(c>='a'&&c<='z')
			Keyword( c,KEYWORD,KNLength,infile,table_key,table_ID,
			table_operator,table_delimiter);
	    else if((c>='A'&&c<='Z')||c=='_')
		{
			 
			string strtemp;
		    Identify( c,infile,strtemp,table_ID,table_operator,table_delimiter);  
		}
	    else if((c=='\"')||(c=='\''))
		{
			//cout<<"NUM"<<endl;
            ConstN( c,infile,table_const);
			//cout<<c<<endl;
		}
		else if(c>='0'&&c<='9')
		    ConstNum(c,infile,table_num,table_operator,table_delimiter);
		else if(classfify(c)==2)
			Operator(c,infile,table_operator,table_delimiter);
		else if(classfify(c)==1)
			Delimiter(c,table_delimiter );

		else
		{
			if(c==10||c==13)
				colume++;
		}
	}
	infile.close();
    //写文件
	Outputfile(table_key,"table_key.txt",3);
    Outputfile(table_ID,"table_ID.txt",1);
	Outputfile(table_delimiter,"table_delimiter.txt",5);
	Outputfile(table_operator,"table_operator.txt",4);
	Outputfile(table_const,"table_const.txt",2);
	Outputfile(table_num,"table_num.txt",2);
	Outputfile("error.txt");
    //进主菜单
    Manager(table_key,table_ID,table_operator,table_delimiter,table_const,table_num);
	//
    
	return 0;
  
}

bool Keyword(char c,string *KEYWORD,int KNLength,
			 ifstream &infile,table &table_key,table &table_ID
			 ,table &table_operator,table &table_delimiter)
{
	
	string keystemp;
	int i=0;
	for(;i<KNLength;i++)
	{
		int k=0;
		//如果已经提取的有字符了
		if(keystemp.length()!=0)
		{
			for(;k<keystemp.length();k++)
			{
				if(keystemp[k]!=KEYWORD[i][k])break;
				else continue;
			}
		}
		//如果不匹配
		if(k!=keystemp.length())continue;
        //判断是否匹配
		for(int j=k;j<KEYWORD[i].length();j++)
		{
			
			if(c!=KEYWORD[i][j])
				break;
			else 
			{
				keystemp+=c;//如果匹配,加入keystemp
				if(infile.get(c)) //读取下一个字符
				{
					if((c>='a'&&c<='z')||c=='_')continue;
					switch(classfify(c))
					{
					case 0://ERROR
						   ERROR[error]=colume;
						   error++;
						   return 0;
					case 1:if(j==KEYWORD[i].length()-1)//如果和关键字匹配
							 {  
				               Getword(table_key,keystemp);
							   Delimiter(c,table_delimiter);
			        	       return 1;
							 }
						     else//如果和关键字不匹配
							 {
								 Getword(table_ID,keystemp);
						    	 Delimiter(c,table_delimiter);
							    return 0;
							 } 
					case 2:if(j==KEYWORD[i].length()-1)//如果和关键字匹配
							 { //如果空间不够再增加20
				               Getword(table_key,keystemp);
                               Operator(c,infile,table_operator,table_delimiter);
			        	       return 1;
							 }
						     else//如果和关键字不匹配
							 {
								Getword(table_ID,keystemp);
						    	Operator(c,infile,table_operator,table_delimiter);
							    return 0;
							 }
					case 3:if(c==' ')
						   {
							  if(j==KEYWORD[i].length()-1)
							 {
								 Getword(table_key,keystemp);
								 
								 return 1;
							 }
						     else 
							 {
								 Getword(table_ID,keystemp);
								 return 0;
							 }
						   }
						   else if(c==10||c==13)
						   {
							  if(j==KEYWORD[i].length()-1)
							 {
								 Getword(table_key,keystemp);
								 colume++;
								 return 1;
							 }
						     else 
							 {
								 Getword(table_ID,keystemp);
								 colume++;
								 return 0;
							 }
						   }
					}
				
				}
				else//如果是最后结尾
				{
					if(j==KEYWORD[i].length()-1)
						Getword(table_key,keystemp);
				}
			}

		}
	}
	if(i==KNLength)
	{
		Identify( c,infile,keystemp,table_ID,table_operator,table_delimiter);
		return 0;
	}
	//cout<<"ID  "<<c<<endl;
} 

bool Identify(char c,ifstream &infile,string &strtemp,table &table_ID
			  ,table &table_operator,table &table_delimiter)
{
	while(1)
	{
	   if((c>='0'&&c<='9')||(c>='A'&&c<='Z')||(c>='a'&&c<='z')||c=='_')
		 strtemp+=c;
	   else
	   {
		   switch(classfify(c))
		   {
	        case 0:ERROR[error]=colume;
				   error++;
		         return 0;
            case 1:Getword(table_ID,strtemp);
		           Delimiter(c,table_delimiter);
		          return 1;
    	    case 2:Getword(table_ID,strtemp);
		          //CALL OPERATOR
			      	Operator(c,infile,table_operator,table_delimiter);
		           return 1;
	        case 3:Getword(table_ID,strtemp);
		          if(c==13||c==10)
			      colume++;
		          return 1;
		   }
	   }
	   if(!infile.get(c))
		   break;
	}
	return 0;

}

bool ConstN(char c,ifstream &infile,table &table_const)
{
	bool b=0;
	if(c=='\"')
		b=ConstStr(c,infile,table_const);
	else//(c=='\'')
		b=ConstChar(c,infile,table_const);
    
	return b;
}
bool ConstStr(char c,ifstream &infile,table &table_const)
{
	string strstemp="\"";
	while(infile.get(c))
	{
		if(c!='\"')
			strstemp+=c;
		else break;

	}
	strstemp+='\"';
    Getword(table_const, strstemp);
	return 1;

}
//提取字符常量
bool ConstChar(char c,ifstream &infile,table &table_const)
{
	string strstemp="\'";
	infile.get(c);
	strstemp+=c;
	infile.get(c);
	strstemp+=c;
	
	Getword(table_const, strstemp);
	return 1;
}

//提取数字常量
bool ConstNum(char c,ifstream &infile,tablenum &table_num,
			  table &table_operator,table &table_delimiter)
{//  1
	double temp=0;//存放当前数据
	int locatespot=1;//当前输入数字离小数点位置
	double power=0;//权值
	bool spot_appear=0;//小数点是否出现0表示没出现1表示出现
	bool E_appear=0;//E或者e是否出现0表示没出现,1表示出现
	bool add_sub=0;//E后面的数字0为加,1为减
	bool num=0;//E后面是否有数字,如果有则1,否则0
	while(1)
	{// 2
		switch(classify_num(c))
		{// 3 
		case 0://ERROR
			ERROR[error]=colume;
			error++;
			return 0;
		case 1:Getnum(table_num,temp);//当遇到界符,提取当前数据
			   Delimiter(c,table_delimiter);//提取界符
			   return 1;//返回
		case 2://如果是构成数字含义的字符0-9,+,-,E,e,.
			   if(E_appear!=1)//E未出现
			   {//4
				   if(spot_appear!=1)//小数点未出现
				   {//5
					   if(c>='0'&&c<='9')//如果是数字则运算提取
					   {
						   temp=temp*10+(c-48);  
					   }
					   else if(c=='.')//如果是小数点则标记
					   {
						   spot_appear=1; 
						   Delimiter(c,table_delimiter);//提取界符
					   }
                       else if(c=='E'||c=='e')//如果是E或者e,标记
						   E_appear=1; 
					   else //+|- 
					   {//6
						   //
						   Getnum(table_num, temp);
						   //CALL OPERATOR
						   Operator(c,infile,table_operator,table_delimiter);
						   return 1;
						  
					   }//6
					   
				   }//5
				   else //spot_appear==1
				   {//5.1
					   //
					   if(c>='0'&&c<='9')//如果数字则提取事实上算的是小数部分,整数部分没变
					   {//6.1
						   temp=temp+(c-48)*pow(10.0,double(0-locatespot));
						   locatespot++;
					   }//6.1
					   else if(c=='e'||c=='E')
					   {//6.2
						   if(locatespot==1)//ERROR ,E出现在小数点后
						   {
							   ERROR[error]=colume;//加入错误信息数组
							   return 0;
						   }
						   else E_appear=1;
					   }//6.2
                       else if(c=='-'||c=='+')//如果遇到+或者-
					   {//6.3
						   //提取运算符
						   Operator(c,infile,table_operator,table_delimiter);
						   if(locatespot==1)//error如果+或者-出现于小数点后,错误
						   {
							   ERROR[error]=colume;
							   error++;
						   }
						   else //如果+和-当前表示运算符正确则提取数字
						   {//7
							   Getnum(table_num,temp);
							   //CALL OPERATOR
							   Operator(c,infile,table_operator,table_delimiter);
							   return 1;
							   
						   }//7
					   }//6.3
					   else //(c=='.')//ERROR 小数点再次出现
					   {
                          ERROR[error]=colume;
						  error++;
						  return 0;
					   }
						   
				   }//5.1 
			   }//4
			   else //E或者e出现
			   {//4.1
				    
				  if(c=='-'&&num==0)//-紧紧出现在E后面
				  {
					  add_sub=1;//E的权值为负数
					  Operator(c,infile,table_operator,table_delimiter);
				  }
				  else if(c=='+'&&num==0)//+紧紧出现于E后面
				  {
					  add_sub=0;//E的权值为正数
					  Operator(c,infile,table_operator,table_delimiter);
				  }
				  else if(c>='0'&&c<='9')
				  {//5.2
					  //计算E的权值

⌨️ 快捷键说明

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