analyst.cpp

来自「一个简单的词法分析器」· C++ 代码 · 共 397 行

CPP
397
字号
// ANALYST.cpp: implementation of the ANALYST class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "ANALYST.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

ANALYST::ANALYST()
{
	char *key[]={"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++语言关键字
    char *limit[]={"+=","-=","*=","/=","==","!=","&&","||",">=","<=",">>","<<","--","++",
					"->","#","(",")","[","]",".","!","~","*","/","%","+","-","<",">",
                  "=",",",";","{","}","_","'",":","&"};//运算、限界符
	Line=1;
	Errorno=0;
	fstream outfile;
    int i,j;
	outfile.open("Key.txt",ios::out);     //创建关键字表并写入关键字
	for(i=0;i<32;i++)
	outfile<<key[i]<<endl;
	outfile.close();
	outfile.open("Limit.txt",ios::out);    //创建运算符、界符表并写入运算符、界符
	for(j=0;j<39;j++)
	outfile<<limit[j]<<endl;
	outfile.close();
	outfile.open("Bsf.txt",ios::out);   //创建标识符表
	outfile.close();
	outfile.open("Data.txt",ios::out);        //创建数据表
	outfile.close();
	outfile.open("Output.txt",ios::out);        //创建目标代码文件
	outfile<<'1'<<"  ";
	outfile.close();
	outfile.open("Error.txt",ios::out);      //创建出错记录文件
	outfile.close();
}
ANALYST::~ANALYST()
{
}
void ANALYST::Bsfdeal(char *word)                         //关键字,标识符处理函数
{
	fstream  outfile,infile,outchar;
	int number=0,find=0,i;
	char ch;
	char temp[30];
	infile.open("Key.txt",ios::in);                      //打开关键字表,寻找匹配关键字
	infile.get(ch);                         
	while(ch!=EOF&&ch!='\n')
	{
		i=0;
		while(ch!='\n')
		{
			temp[i++]=ch;
			infile.get(ch);
		}
		temp[i]='\0';
		number++;
		if(strcmp(temp,word)==0)
		{ 
			outchar.open("Output.txt",ios::app);                    //若找到匹配关键字,写入目标代码文件
			outchar<<word<<"  ";
			outchar.close();
			infile.close();                                           
			find=1;	
		}
		else                                                      //向下搜寻
			infile.get(ch);
	}
	infile.close();
	if(find==0)                                                  //若不是关键字,则搜寻标识符
	{
		infile.open("Bsf.txt",ios::in);
		infile.get(ch);
		while(ch!=EOF&&ch!='\n')
		{
			i=0;
			while(ch!='\n')
			{	
				temp[i++]=ch;
				infile.get(ch);
			}
			temp[i]='\0';
			number++;
		if(strcmp(temp,word)==0)                                //若找到匹配标识符,写入目标代码文件
			{
				outchar.open("Output.txt",ios::app);
				outchar<<word<<"  ";
				outchar.close();
				infile.close();
				find=1;
			}
			else 
				infile.get(ch);                                     //向下搜寻
		}
		infile.close();
		if(find==0)                              // 若未找到匹配标识符,则为新标识符,写入标识符表
		{
			outfile.open("Bsf.txt",ios::app);
			outfile<<word<<endl;
			outfile.close();
			outchar.open("Output.txt",ios::app);     //新标识符写入目标代码文件
			outchar<<word<<"  ";
			outchar.close();
		}
	}
}
void ANALYST::Intdeal(char *word)              //数据处理函数
{
	fstream  infile,outfile,outchar;
	int number=0,find=0,i;
	char ch;
	char temp[30];
	infile.open("Data.txt",ios::in);             //打开数据表,寻找匹配数据
	infile.get(ch);
	while(ch!=EOF&&ch!='\n')
	{
	    i=0;
		while(ch!='\n')
		{
			temp[i++]=ch;
			infile.get(ch);
		}
		temp[i]='\0';
		number++;
		if(strcmp(temp,word)==0)              //若找到匹配数据,写入目标代码文件
		{
			outchar.open("Output.txt",ios::app);
			outchar<<word<<"  ";
			outchar.close();
			infile.close();
			find=1;
		}
		else                             //否则,向下搜寻
			infile.get(ch);
		
	}
	infile.close();
	if(find==0)                         //若未找到,则写入数据表
	{
		outfile.open("Data.txt",ios::app);
		outfile<<word<<endl;
		outfile.close();
		outchar.open("Output.txt",ios::app);   //写入目标代码文件
		outchar<<word<<"  ";
		outchar.close();
	}
}
void ANALYST::Limitdeal(char *word, int line,fstream Infile)    //运算符、界符处理函数
{                   
	int number=0,find=0,i;
	char ch;
	char temp[30];
	fstream infile,outfile, outchar;
	infile.open("Limit.txt",ios::in);           //打开界符表,开始搜寻
	infile.get(ch);
	while(ch!='#'&&ch!='\n')                        //先搜寻双字符
	{
	    i=0;
		while(ch!='\n') 
		{
			temp[i++]=ch;
			infile.get(ch);
		}
		temp[i]='\0';
		number++;
		if(strcmp(temp,word)==0)              //若找到,写入目标代码文件
		{
			outchar.open("Output.txt",ios::app); 
			outchar<<word<<"  ";
			outchar.close();
			infile.close();
		    find=1;
		}	
		
		else
			infile.get(ch);
	}
	if(find==0)                                     //若不是双字符,则搜寻单字符
	{
		Infile.seekg(-1,ios::cur);
		word[1]='\0';
		while(ch!=EOF&&ch!='\n')
		{	
			i=0;
			while(ch!='\n')
			{
				temp[i++]=ch;
				infile.get(ch);
			}
			temp[i]='\0';
			number++;
			if(strcmp(temp,word)==0)             //若为单字符,写入目标代码文件
			{
				outchar.open("Output.txt",ios::app);
				outchar<<word<<"  ";
				outchar.close();
				infile.close();
				find=1;

			}
			else 
				infile.get(ch);
		}
		infile.close();
		if(find==0)                      //否则为无法识别字符,进行错误处理
		{
			Errorno++;
			outfile.open("Error.txt",ios::app);       //错误信息写入出错记录文件
			outfile<<"第"<<line<<"行"<<"字符"<<" "<<word<<" "<<"出错"<<endl;
			outfile.close();
			outfile.open("Output.txt",ios::app);     //标记出错点
			outfile<<"^_^";
			outfile.close();
		} 
	} 
}
void ANALYST::Scanner()                                 //扫描函数
{
	char temp[30],line[80];
	char ch;
	char*word;
    int i;
	fstream Infile, Outfile,Intxt;
	char Filename[20];
	cout<<"请输入需编译的文件名:";
	cin>>Filename;
	Infile.open(Filename,ios::nocreate|ios::in);       //打开需编译的文件
	while(! Infile)
    { 
		cout<<"此文件不存在"<<endl;
       	exit(0);
    }
	cout<<endl<<endl;
	cout<<"需编译的文件内容为:"<<endl;
	Intxt.open(Filename,ios::in);            //输出需编译的文件内容
	while(Intxt.getline(line,80))
		cout<<line<<endl;
	Intxt.close();
    Infile.get(ch);                                     //开始扫描文件
	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')))
            {
                temp[i++]=ch;
                Infile.get(ch);
			}
			word=new char[i+1];
			memcpy(word,temp,i);
			word[i]='\0';	
            Bsfdeal(word);
			delete []word;
			Infile.seekg(-1,ios::cur);
        }
        else if(ch>='0'&&ch<='9')
        {                                                //识别数字
            while(ch>='0'&&ch<='9')
            {
                temp[i++]=ch;
                Infile.get(ch);
            }
            word=new char[i+1];
			memcpy(word,temp,i);
			word[i]='\0';
            Intdeal(word);
			delete []word;
			Infile.seekg(-1,ios::cur);
        }
        else if((ch==' ')||(ch=='\t'))                //消除空格符和水平制表符
		{
		}                                                           
		else if(ch=='\n')                           //消除回车并记录行数
		{
			Line++;
			Outfile.open("Output.txt",ios::app);
			Outfile<<endl;
			Outfile<<Line<<"  ";
            Outfile.close();                               
		}
		else if(ch=='/')
        {                                                            //消除注释
			Infile.get(ch);
			if(ch=='=')                                               
			{                                                    //判断是否为‘/=’符号
				Outfile.open("Output.txt",ios::app);
				Outfile<<"/="<<'  ';
                Outfile.close();
			}
			else if(ch=='*')
			{                                                    //若为多行注释的开始,消除包含在里面的所有字符
				int count=0;
				Infile.get(ch);
				while(count!=2)
                {                                        //当扫描到‘*’且紧接着下一个字符为‘/’才是注释的结束
					count=0;
					while(ch!='*')
					Infile.get(ch);
					count++;
					Infile.get(ch);
					if(ch=='/')
						count++;
					else
						Infile.get(ch);
				}
			}
			else if(ch=='/')                          //消除单行注释
			{
				do
					Infile.get(ch);	
				while(ch!='\n'&&ch!=EOF);
				if(ch=='\n')
				{
					Line++;
					Outfile.open("Output.txt",ios::app);
					Outfile<<endl;
					Outfile<<Line<<"  ";
					Outfile.close();
				}
				else
					Infile.seekg(-1,ios::cur);
			}
			else if(ch==EOF)                         //若为文件末尾,则后退一个字符
				Infile.seekg(-1,ios::cur);
			else
			{
				Outfile.open("Output.txt",ios::app);
				Outfile<<"/"<<"   ";
				Outfile.close();
				Infile.seekg(-1,ios::cur);
			}
		}
		else if(ch=='"')     
		{                                                //处理包含在双引号中的字符串常量 
			Outfile.open("Output.txt",ios::app);
			Outfile<<ch<<" ";
			do
			{
				Infile.get(ch);
				Outfile<<ch;
			}
			while(ch!='"');
			Outfile<<" ";
			Outfile.close();
		}
		else
		{                                  //首字符为其它字符,即运算符,界符或非法字符
			temp[0]=ch;
			Infile.get(ch);             //读入下一个字符,判断是否为双字符运算、限界符
			if(ch!=EOF&&ch!='\n')
			{                                      
				temp[1]=ch;
				word=new char[3];
				memcpy(word,temp,2);
				word[2]='\0';
				Limitdeal(word,Line,Infile);   //若为运算符界符,调用函数进行处理
				delete []word;
				
			}
			else
			{                       //若读入的下一个字符为文件结束符,处理后需后退
				word=new char[2];
				memcpy(word,temp,1);
				word[1]='\0';
				Limitdeal(word,Line,Infile);
				delete []word;
				Infile.seekg(-1,ios::cur);
			}
		}
		Infile.get(ch);
	}
    Infile.close();
	cout<<endl<<endl;
	cout<<"编译后的目标代码为:"<<endl;
    Infile.open("Output.txt",ios::in);            //输出编译后的目标代码
	while(Infile.getline(line,80))
		cout<<line<<endl;
	Infile.close();
	if(Errorno!=0)
	{
		cout<<"文件共有"<<Errorno<<"个错误"<<endl;
		Infile.open("Error.txt",ios::in);
		while(Infile.getline(line,80))             //输出错误信息
			cout<<line<<endl;
		Infile.close();
	}
	else 
	cout<<"文件错误0个"<<endl;
}

⌨️ 快捷键说明

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