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

📄 fenxi.cpp

📁 编译原理课程设计
💻 CPP
字号:
#include "fenxi.h"
#include<ctype.h>
#include<fstream>
#include<string>
#include<iostream>
using namespace std;

/*================================================================ 
* 函数名:    CiFaFenXi
* 功能描述:   词法分析 (public)
* 返回值:    void
================================================================*/
void CFenXi::CiFaFenXi()
{
	///*
	cout<<"filename:";
  	string filename;
	cin>>filename;
	ifstream infile;
	infile.open(filename.c_str());
	if(!infile)exit(0);
	int x=0;
	while(!infile.eof())
	{
		infile.get(m_str[x++]);
	}
	m_str[--x]='\0';
	//*/
	bool flag=false;
	char token[20];
	int k,v;
	
	init();

	for (int i=0;i<m_n;i++)  //当第2次调用该函数时,就要释放前1次的资源
		delete m_cifa[i];
	
	int n=0;		//用于指示当前的字符
	m_n=0;			//词法结果的个数
	
	while (m_str[n])
	{
		if (flag)
		{
			while (!((m_str[n]=='*')&&(m_str[n+1]=='/')))
			{
				if (m_str[n]) 
					n++;
				else 
					break;
			}
			
			if (m_str[n])
			{
				n++;
				n++;
				flag=false;
			}
		}
		while (1)
		{
			while ((m_str[n]==32) || (m_str[n]==9))
				n++;
			
			if (!((m_str[n]==13) && (m_str[n+1]==10)))
				break;
			
			n++;
			n++;
		}

		
		if (isalpha(m_str[n]))		//字母
		{
			k=0;
			while (1)
			{
				if (k<19)				//标志符的长度为20
					token[k++]=m_str[n++];
				else 
					n++;
				
				if (!isalnum(m_str[n])) //如果不是数字或字母就退出
					break;
			}
			
			token[k]=0;
			v=FindInKWTab(token);	//查找关键词表
			if (v)	//如果是关键词
			{
				m_cifa[m_n]=new CIFA;
				m_cifa[m_n]->nValue=0;
				m_cifa[m_n]->nType=v;
				strcpy(m_cifa[m_n]->szText,token);
				m_cifa[m_n]->nAddr=n-k;
				m_n++;
			}
			else   //普通标志符
			{
				m_cifa[m_n]=new CIFA;
				
			    /*----------在词法分析结果中查找-----------*/
				int vv=1;
				for (int i=0;i<m_n;i++)
				{
					if (m_cifa[i]->nType==1)
					{
						vv++;
						if (!::stricmp(m_cifa[i]->szText,token))
							m_cifa[m_n]->nValue= m_cifa[i]->nValue;
					}
				}
				m_cifa[m_n]->nValue=vv;
			    /*---------------------------------------*/

				m_cifa[m_n]->nType=1;
				strcpy(m_cifa[m_n]->szText,token);
				m_cifa[m_n]->nAddr=n-k;
				m_n++;
			}
		}
		else if (isdigit(m_str[n]))	//数字
		{
			k=0;
			bool error=false;
			while (1)
			{
				if (k<=8) 
					token[k++]=m_str[n++];
				else
				{
					error=true;
					n++;
				}
				if (!isdigit(m_str[n])) 
					break;
			}
			token[k]=0;
			v=::strtol(token,NULL,10);
			if (error)
			{
				m_cifa[m_n]=new CIFA;
				m_cifa[m_n]->nValue=1;
				m_cifa[m_n]->nType=0;
				strcpy(m_cifa[m_n]->szText,token);
				m_cifa[m_n]->nAddr=n-k;
				m_n++;
			}
			else
			{
				m_cifa[m_n]=new CIFA;
				m_cifa[m_n]->nValue=v;
				m_cifa[m_n]->nType=2;
				strcpy(m_cifa[m_n]->szText,token);
				m_cifa[m_n]->nAddr=n-k;
				m_n++;
			}
		}
		else
			switch (m_str[n])	//其他符号
			{
			case '+':
			case '-':
			case '*':
			case '~':
			case '&':
			case '|':
			case '=':
			case ';':
			case '.':
			case ',':
			case '(':
			case ')':
				token[0]=m_str[n];
				token[1]=0;
				v=FindInKWTab(token);

				m_cifa[m_n]=new CIFA;
				m_cifa[m_n]->nValue=0;
				m_cifa[m_n]->nType=v;
				strcpy(m_cifa[m_n]->szText,token);
				m_cifa[m_n]->nAddr=n;

				m_n++;
				n++;
				break;

			case '\0':
				break;

			case '/':
				switch (m_str[n+1])
				{
				case '*':
					n++;
					n++;
					flag=true;
					break;
				default:
					token[0]=m_str[n];
					token[1]=0;
					v=FindInKWTab(token);
					m_cifa[m_n]=new CIFA;
					m_cifa[m_n]->nValue=0;
					m_cifa[m_n]->nType=v;
					strcpy(m_cifa[m_n]->szText,token);
					m_cifa[m_n]->nAddr=n;
					m_n++;
					n++;
				}
				break;

				case '<':
					switch (m_str[n+1])
					{
					case '=':
						token[0]=m_str[n];
						token[1]=m_str[n+1];
						token[2]=0;
						v=FindInKWTab(token);
						m_cifa[m_n]=new CIFA;
						m_cifa[m_n]->nValue=0;
						m_cifa[m_n]->nType=v;
						strcpy(m_cifa[m_n]->szText,token);
						m_cifa[m_n]->nAddr=n;
						m_n++;
						n++;
						n++;
						break;
					case '>':
						token[0]=m_str[n];
						token[1]=m_str[n+1];
						token[2]=0;
						v=FindInKWTab(token);
						m_cifa[m_n]=new CIFA;
						m_cifa[m_n]->nValue=0;
						m_cifa[m_n]->nType=v;
						strcpy(m_cifa[m_n]->szText,token);
						m_cifa[m_n]->nAddr=n;
						m_n++;
						n++;
						n++;
						break;

					default:
						token[0]=m_str[n];
						token[1]=0;
						v=FindInKWTab(token);
						m_cifa[m_n]=new CIFA;
						m_cifa[m_n]->nValue=0;
						m_cifa[m_n]->nType=v;
						strcpy(m_cifa[m_n]->szText,token);
						m_cifa[m_n]->nAddr=n;
						m_n++;
						n++;
					}
					break;

					case '>':
						switch (m_str[n+1])
						{
						case '=':
							token[0]=m_str[n];
							token[1]=m_str[n+1];
							token[2]=0;
							v=FindInKWTab(token);
							m_cifa[m_n]=new CIFA;
							m_cifa[m_n]->nValue=0;
							m_cifa[m_n]->nType=v;
							strcpy(m_cifa[m_n]->szText,token);
							m_cifa[m_n]->nAddr=n;
							m_n++;
							n++;
							n++;
							break;

						default:
							token[0]=m_str[n];
							token[1]=0;
							v=FindInKWTab(token);
							m_cifa[m_n]=new CIFA;
							m_cifa[m_n]->nValue=0;
							m_cifa[m_n]->nType=v;
							strcpy(m_cifa[m_n]->szText,token);
							m_cifa[m_n]->nAddr=n;
							m_n++;
							n++;
						}
						break;

						case ':':
							switch (m_str[n+1])
							{
							case '=':
								token[0]=m_str[n];
								token[1]=m_str[n+1];
								token[2]=0;
								v=FindInKWTab(token);
								m_cifa[m_n]=new CIFA;
								m_cifa[m_n]->nValue=0;
								m_cifa[m_n]->nType=v;
								strcpy(m_cifa[m_n]->szText,token);
								m_cifa[m_n]->nAddr=n;
								m_n++;
								n++;
								n++;
								break;

							default:
								token[0]=m_str[n];
								token[1]=0;
								v=FindInKWTab(token);
								m_cifa[m_n]=new CIFA;
								m_cifa[m_n]->nValue=0;
								m_cifa[m_n]->nType=v;
								strcpy(m_cifa[m_n]->szText,token);
								m_cifa[m_n]->nAddr=n;
								m_n++;
								n++;
							}
							break;

							default:
								token[0]=m_str[n];
								token[1]=0;
								m_cifa[m_n]=new CIFA;
								m_cifa[m_n]->nValue=2;
								m_cifa[m_n]->nType=0;
								strcpy(m_cifa[m_n]->szText,token);
								m_cifa[m_n]->nAddr=n;
								m_n++;
								n++;
			} 

		if (m_n==10000-2)	//词法分析的结果的个数规定为10000
		{
			m_cifa[m_n]=new CIFA;
			m_cifa[m_n]->nValue=99;
			m_cifa[m_n]->nType=0;
			strcpy(m_cifa[m_n]->szText,"");
			m_cifa[m_n]->nAddr=n-1;
			m_n++;
			break;
		}
	} 

	m_cifa[m_n]=new CIFA;
	m_cifa[m_n]->nValue=0;
	m_cifa[m_n]->nType=-1;	//结束符
	strcpy(m_cifa[m_n]->szText,"");
	m_cifa[m_n]->nAddr=0;
	m_n++;
    //cout<<"OK1";
	return;
}




/*================================================================ 
* 函数名:    FindInKWTab(char * a)
* 功能描述:   在关键字表中查找  (protected)
* 返回值:    int (如果找到返回在表中的位置,否则返回0)
================================================================*/
int CFenXi::FindInKWTab(char * a)
{
	for (int i=0;i<50;i++)
		if (!::stricmp(m_szKW[i],a))   //找到
			return i;

		return 0; //未找到
}



/*================================================================ 
* 函数名:    YuFaFenXi
* 功能描述:   语法分析 (public)
* 返回值:    void
* 作 者:     程红秀 2005年6月15日
================================================================*/
void CFenXi::YuFaFenXi()
{
	if (m_n==0) 
		return;		//未进行词法分析
	
	m_nCur=0;		//m_nCur用语指示词法分析结果表中单词的位置
    while(m_cifa[m_nCur]->nType!=-1)
	{
			if (y_FuZhiYuJu())
				cout<<"OK,赋值语句正确!"<<endl;
			else cout<<"ERROR,赋值语句有错!"<<endl;//从 程序 开始
			m_nCur++;
	}
	return;
}



/*================================================================ 
* 函数名:    y_FuZhiYuJu
* 功能描述:   赋值语句 (protected)
* 返回值:    void
* 示例:      y:=219;
================================================================*/
bool CFenXi::y_FuZhiYuJu()
{
	switch (m_cifa[m_nCur]->nType)
	{
	case 1:		//id
		break;
	default:
		m_nErrNo=20; //缺少标识符!
		m_nErrAddr=m_nCur;
		return false;
	}

	m_nCur++;

	switch (m_cifa[m_nCur]->nType)
	{
	case 29:	//:=
		break;
	default:
		m_nErrNo=21;  //缺少赋值符号“ := ”!
		m_nErrAddr=m_nCur;
		return false;
	}


	m_nCur++;

	if (!y_BiaoDaShi()) 
		return false;

    //m_nCur++;
    switch (m_cifa[m_nCur]->nType)
	{
	case 30:			//;
		break;
	default:
		m_nErrNo=5;		//缺少“ ; ”符号!
		m_nErrAddr=m_nCur;
		cout<<this->m_szErrMsg[5];
		return false;
	}
	return true;
}

/*================================================================ 
* 函数名:    y_BiaoDaShi
* 功能描述:   表达式 (protected)
* 返回值:    void
* 示例:    z:=4+z+(1+2+6+x)*3*y*5+7;
================================================================*/
bool CFenXi::y_BiaoDaShi()
{
	if (!y_Xiang())
		return false;
	while (m_cifa[m_nCur]->nType==16)	//+
	{
		m_nCur++;
		if (!y_Xiang()) 
			return false;
	}
	return true;
}



/*================================================================ 
* 函数名:    y_Xiang
* 功能描述:   项 (protected)
* 返回值:    void
================================================================*/
bool CFenXi::y_Xiang()
{
	if (!y_YinZi()) 
		return false;

	while (m_cifa[m_nCur]->nType==18)//*
	{
		m_nCur++;
		if (!y_YinZi())
			return false;
	}

	return true;
}



/*================================================================ 
* 函数名:    y_YinZi
* 功能描述:   因子 (protected)
* 返回值:    void
================================================================*/
bool CFenXi::y_YinZi()
{
	switch (m_cifa[m_nCur]->nType)
	{
	case 1:			//id
		m_nCur++;
		break;

	case 2:			//num
		m_nCur++;
		break;

	case 33:		//(
		m_nCur++;

		if (!y_BiaoDaShi())  //递归调用
			return false;

		switch (m_cifa[m_nCur]->nType)
		{
		case 34:	//)
			break;
		default:
			m_nErrNo=17;  //缺少 “ ) ”符号!
			m_nErrAddr=m_nCur;
			return false;
		}
		m_nCur++;

		break;

		default:
			m_nErrNo=28; //缺少《因子》,应为 (,ID,NUMBER"
			m_nErrAddr=m_nCur;
			return false;
	}
	return true;
}


/*================================================================ 
* 函数名:    init
* 功能描述:   用于初始化关键字表和错误信息表   (protected)
* 返回值:    void
================================================================*/
void CFenXi::init()
{
 	strcpy(m_szKW[0],"");
	strcpy(m_szKW[1],"");//标识符
	strcpy(m_szKW[2],"");//正整数
	strcpy(m_szKW[3],"program");
	strcpy(m_szKW[4],"var");
	strcpy(m_szKW[5],"procedure");
	strcpy(m_szKW[6],"begin");
	strcpy(m_szKW[7],"end");
	strcpy(m_szKW[8],"if");
	strcpy(m_szKW[9],"then");
	strcpy(m_szKW[10],"else");
	strcpy(m_szKW[11],"while");
	strcpy(m_szKW[12],"do");
	strcpy(m_szKW[13],"call");
	strcpy(m_szKW[14],"integer");
	strcpy(m_szKW[15],"real");
	strcpy(m_szKW[16],"+");
	strcpy(m_szKW[17],"-");
	strcpy(m_szKW[18],"*");
	strcpy(m_szKW[19],"/");
	strcpy(m_szKW[20],"~");
	strcpy(m_szKW[21],"&");
	strcpy(m_szKW[22],"|");
	strcpy(m_szKW[23],"<");
	strcpy(m_szKW[24],"<=");
	strcpy(m_szKW[25],">");
	strcpy(m_szKW[26],">=");
	strcpy(m_szKW[27],"=");
	strcpy(m_szKW[28],"<>");
	strcpy(m_szKW[29],":=");
	strcpy(m_szKW[30],";");
	strcpy(m_szKW[31],".");
	strcpy(m_szKW[32],",");
	strcpy(m_szKW[33],"(");
	strcpy(m_szKW[34],")");
	strcpy(m_szKW[35],":");
	strcpy(m_szKW[36],"/*");
	strcpy(m_szKW[37],"*/");
	strcpy(m_szKW[38],"");
	strcpy(m_szKW[39],"");
	strcpy(m_szKW[40],"");
	strcpy(m_szKW[41],"");
	strcpy(m_szKW[42],"");
	strcpy(m_szKW[43],"");
	strcpy(m_szKW[44],"");
	strcpy(m_szKW[45],"");
	strcpy(m_szKW[46],"");
	strcpy(m_szKW[47],"");
	strcpy(m_szKW[48],"");
	strcpy(m_szKW[49],"");
	strcpy(m_szErrMsg[0],"正确!");
	strcpy(m_szErrMsg[5],"缺少“ ; ”符号!");
}

void main()
{
	CFenXi C;
	C.CiFaFenXi();
	cout<<"------------------------------------------"<<endl;
	cout<<C.m_str<<endl<<"------------------------------------------"<<endl;
	for(int i=0;C.m_cifa[i]->nType!=-1;i++)
	cout<<C.m_cifa[i]->nType<<" "<<C.m_cifa[i]->nValue<<" "<<C.m_cifa[i]->szText<<endl;
	//cout<<C.m_cifa[i]->nType<<" "<<C.m_cifa[i]->nValue<<" "<<C.m_cifa[i]->szText<<endl;
	cout<<"------------------------------------------"<<endl;
	C.YuFaFenXi();
	//cout<<C.m_nErrNo;
	//cout<<C.m_szErrMsg[0];
}

⌨️ 快捷键说明

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