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

📄 ccifafenxi.cpp

📁 编译器,词法分析和语法分析,里面利用到了哈希表来加快搜索字符表速度.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//CCiFaFenXi.cpp

#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <iostream.h>
#include "CFenCi.h"

CFenXi::CFenXi()
{
		init();
		for(int i=0;i<10000;i++)
				m_cifa[i] = NULL; 
}

/*================================================================ 
* 函数名:    ShengMing
* 功能描述:   声明 (protected)
* 返回值:    void
================================================================*/
bool CFenXi::ShengMing()
{
	switch (m_cifa[m_nCur]->nType)
	{
	case 14:		//Interger
	case 15:		//real
		if (!BianliangShengMing())	//变量声明
			return false;
		break;

	case 5:			//procedure
		if (!GuoChengShengMing()) //过程声明
			return false;
		break;

	default:
		m_nErrNo=11;		//缺少声明(integer,real,procedure)
		m_nErrAddr=m_nCur;
		return false;
	}
	return true;
}

/**************************************** 
* 函数名:    BianliangShengMing
* 功能描述:   变量声明	(protected)
* 返回值:    void
* 示例:	 Integer x,y,z;
******************************************/
bool CFenXi::BianliangShengMing()
{

	switch(m_cifa[m_nCur]->nType)
	{
	case 14:	//Interger
	case 15:	//real
		break;

	default:
		m_nErrNo=12;	//缺少变量类型 integer 或 real!
		m_nErrAddr=m_nCur;
		return false;
	}

	m_nCur++;

	if( m_cifa[m_nCur]->nType !=1)
	{
		m_nErrNo=14;	//变量声明后缺少标识符!
		m_nErrAddr=m_nCur;
		return false;
	}

/*	if(!IsRedefine(m_cifa[m_nCur]->szText))
	{
			m_nErrNo=41;//变量重复定义
			return false;
	}
*/
	m_nCur++;

	while (m_cifa[m_nCur]->nType==32)  //32 , 分析用逗号隔开的连续声明的几个变量
	{
		m_nCur++;

		if( m_cifa[m_nCur]->nType !=1) //id
		{
			m_nErrNo=14;  	//变量声明后缺少标识符
			m_nErrAddr=m_nCur;
			return false;
		}

		m_nCur++;
	}

	return true;
}

/***************************************
*函数名:CiFaFenXi
*所属类:CFenXi
*功能:从输入串分离出一个个的单词
****************************************/
bool CFenXi::CiFaFenXi()
{
	bool flag=true;
	char token[20];
	int k,v;
	int line=0;//行序指示标量

	for (int i=0;i<m_n;i++)  //当第2次调用该函数时,就要释放前1次的资源
	{
		delete m_cifa[i];
	}
	
	int n=0;		//用于指示当前的字符
	m_n=0;			//词法结果单词的个数

	//过滤不显示的字符
	while(m_str[n])
	{
			while (1)
		{
			if (m_str[n]=='\r')//过滤回车符
					n++;
			else if(m_str[n]=='\n')//过滤换行符
			{
				line++;
				n++;
			}
			else if(m_str[n]=='\t')//过滤制表符
					n++;
			else if(m_str[n]==' ')//过滤空格
					n++;
			else
					break;
		}
			
	

		//识别可显示字符
		if (isalpha(m_str[n]))		//字母
		{
				k=0;
				while(1)
				{
						if(k<19)				//标志符的长度为20
								token[k++]=m_str[n++];
						else //把超过20的部分过滤掉
								n++;
				
						if (!isalnum(m_str[n])) //如果不是数字或字母就退出
							break;
				}
			
				token[k]=0;
				v=FinKW(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);
						strcpy(m_cifa[m_n]->szDesc, "Reserved word:");
						m_cifa[m_n]->nAddr=n-k;
						m_cifa[m_n]->nLineNo = line;
						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);
						strcpy(m_cifa[m_n]->szDesc, "ID,name=");
						m_cifa[m_n]->nAddr=n-k;
						m_cifa[m_n]->nLineNo = line;
						m_n++;
				}
		}
		else if (isdigit(m_str[n]))	//数字
		{
			k=0;

			while (1)
			{
				if (k<=8) 
					token[k++]=m_str[n++];
				else
				{
					    n++;//过滤长度数字串中超过8的部分
				}
				if (!isdigit(m_str[n])) 
					break;
			}
			token[k]=0;
			v=atoi(token);

			{
				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);
				strcpy(m_cifa[m_n]->szDesc,"NUM,val=");
				m_cifa[m_n]->nAddr=n-k;
				m_cifa[m_n]->nLineNo = line;
				m_n++;
			}
		}
		else
			switch (m_str[n])	//其他符号
			{
			case '+':
			case '-':
			case '*':
			case ';':
			case '~':
			case '&':
			case '.':
			case ',':
			case '(':
			case ')':
				token[0]=m_str[n];
				token[1]=0;
				v=FinKW(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);
				strcpy(m_cifa[m_n]->szDesc," ");
				m_cifa[m_n]->nLineNo = line;
				m_cifa[m_n]->nAddr=n;

				m_n++;
				n++;
				break;

			case '\0':
					n++;
				break;
			case '#':
					nLength = m_n;
					return true;

			case '<':
					switch (m_str[ n+1])
					{
					case '=':
						token[0]=m_str[n];
						token[1]=m_str[n+1];
						token[2]=0;
						v=FinKW(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);
						strcpy(m_cifa[m_n]->szDesc,"小于等于");
						m_cifa[m_n]->nAddr=n;
						m_cifa[m_n]->nLineNo = line;
						m_n++;
						n++;
						n++;
						break;

					case '>':
						token[0]=m_str[n];
						token[1]=m_str[n+1];
						token[2]=0;
						v=FinKW(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);
						strcpy(m_cifa[m_n]->szDesc,"不等于");
						m_cifa[m_n]->nAddr=n;
						m_cifa[m_n]->nLineNo = line;
						m_n++;
						n++;
						n++;
						break;

					default:
						token[0]=m_str[n];
						token[1]=0;
						v=FinKW(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);
						strcpy(m_cifa[m_n]->szDesc,"小于");
						m_cifa[m_n]->nAddr=n;
						m_cifa[m_n]->nLineNo = line;
						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=FinKW(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);
							strcpy(m_cifa[m_n]->szDesc,"大于等于");
							m_cifa[m_n]->nAddr=n;
							m_cifa[m_n]->nLineNo = line;
							m_n++;
							n++;
							n++;
							break;

					default:
							token[0]=m_str[n];
							token[1]=0;
							v=FinKW(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);
							strcpy(m_cifa[m_n]->szDesc,"大于");
							m_cifa[m_n]->nAddr=n;
							m_cifa[m_n]->nLineNo = line;
							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=FinKW(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);
								strcpy(m_cifa[m_n]->szDesc,"赋值运算符");
								m_cifa[m_n]->nAddr=n;
								m_cifa[m_n]->nLineNo = line;
								m_n++;
								n++;
								n++;
								break;

						default:
								token[0]=m_str[n];
								token[1]=0;
								v=FinKW(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);
								strcpy(m_cifa[m_n]->szDesc,"类型说明符号");
								m_cifa[m_n]->nAddr=n;
								m_cifa[m_n]->nLineNo = line;
								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);
							strcpy(m_cifa[m_n]->szDesc,"ddd");
							m_cifa[m_n]->nAddr=n;
							m_cifa[m_n]->nLineNo = line;
							m_n++;
							n++;
							flag=false;
			} 

		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,"");
			strcpy(m_cifa[m_n]->szDesc,"错误");
			m_cifa[m_n]->nAddr=n-1;
			m_cifa[m_n]->nLineNo = line;
			m_n++;
			break;
		}
	} 
	return flag;

}

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

		return 0; //未找到
}

/***************************************** 
* 函数名:    GuoChengYuJu
* 功能描述:   过程语句	 (protected)
* 返回值:    void
* 示例:	Call ab(x,y,z);
******************************************/
bool CFenXi::GuoChengYuJu()
{
	if(m_cifa[m_nCur]->nType !=  13) 	//call,这句不可能执行
	{
		m_nErrNo=26;	//缺少保留字“ call ”!
		m_nErrAddr=m_nCur;
		return false;
	}

	m_nCur++;


	if(m_cifa[m_nCur]->nType !=  1)
	{
		m_nErrNo=27;	//缺少被调过程名标识符!
		m_nErrAddr=m_nCur;
		return false;
	}
	
	m_nCur++;

	if(m_cifa[m_nCur]->nType != 33 )
		return true;

	if (!ShiCan()) //表达式
		return false;

	return true;
}

/******************************** 
* 函数名:    ShiCan
* 功能描述:   实参表 (protected)
* 返回值:    void
*示例:		Call ab(x,y,z);
**********************************/
bool CFenXi::ShiCan()
{
	if(m_cifa[m_nCur]->nType != 33 ) 	//(,这块不可能被执行
	{
		m_nErrNo=16;	//缺少 “ ( ”符号!
		m_nErrAddr=m_nCur;
		return false;
	}


	m_nCur++;

	if (!BiaoDaShi())  //表达式
		return false;

	while (m_cifa[m_nCur]->nType==32)	//,
	{
		m_nCur++;
		if (!BiaoDaShi()) 
			return false;
	}

	if(m_cifa[m_nCur]->nType !=34  )//)
	{
		m_nErrNo=17;	//缺少 “ ) ”符号
		m_nErrAddr=m_nCur;
		return false;
	}

	m_nCur++;
	return true;
}

/******************************************** 
* 函数名:    YuFaFenXi
* 功能描述:   语法分析 (public)
* 返回值:    void
**********************************************/
bool CFenXi::YuFaFenXi()
{

//	if (m_n==0) 
//		return;		//尚未进行词法分析
	
	m_nCur=0;		//m_nCur用语指示词法分析结果表中单词的位置

	if(!ChengXu())		//从 程序 开始
			return false;

	return true;
}

/****************************************** 
* 函数名:    ChengXu
* 功能描述:   分析整个程序 (protected)
* 返回值:    bool
* 示例:
			Program abc;
				这里是程序体	
			.
*******************************************/
bool CFenXi::ChengXu()			//程序
{
 
	if(m_cifa[m_nCur]->nType !=3) 
	{
		m_nErrNo=3;		//缺少关键字 program 
		m_nErrAddr=m_nCur;
		return false;
	}

	m_nCur++;			//分析下一个单词

	if(m_cifa[m_nCur]->nType !=1) //标志符
	{
		m_nErrNo=4;		//program 后缺少标识符!
		m_nErrAddr=m_nCur;
		return false;
	}

	m_nCur++;

	if( m_cifa[m_nCur]->nType !=30) //;
	{
		m_nErrNo=5;		//缺少分号
		m_nErrAddr=m_nCur;
		return false;
	}

	m_nCur++;

	if (!ChengXuTi())  //分析程序体
		return false;

	if(m_cifa[m_nCur]->nType != 31)  	//'.' (程序的最后一个符号)
	{
		m_nErrNo=6;		//缺少程序结束符.
		m_nErrAddr=m_nCur;
		return false;
	}


	return true;
}

/************************************************* 
* 函数名:    ShengMingChuan
* 功能描述:   声明串 用;隔开的多个声明(protected)
* 返回值:    void
**************************************************/
bool CFenXi::ShengMingChuan()
{
	if (!ShengMing()) 		
		return false;

	while (m_cifa[m_nCur]->nType==30 && m_cifa[m_nCur+1]->nType!=6)	//是; 不是begin
	{
		m_nCur++;
		if (!ShengMing()) //递归调用
			return false;
	}
	return true;
}

/**************************************** 
* 函数名:    ChengXuTi
* 功能描述:   分析程序体 (protected)
* 返回值:    bool
* 示例:
***************************************/
bool CFenXi::ChengXuTi()
{
	switch (m_cifa[m_nCur]->nType)
	{
	case 5:			//procedure		
	case 14:		//booleger
	case 15:		//real
 
		if (!ShengMingChuan())   //声明串(用;隔开的多个变量或过程声明)
			return false;

		if(m_cifa[m_nCur]->nType  !=30 ) //;
		{
			m_nErrNo=5;	//缺少;!"
			m_nErrAddr=m_nCur;
			return false;
		}
		
		m_nCur++;
		break;

	case 6:		//begin
			break;

	default:
			m_nErrNo=7;		//缺少程序体,应为 begin,integer,real,procedure 
			m_nErrAddr=m_nCur;
			return false;
	}

	if(m_cifa[m_nCur]->nType !=6)  //begin
	{
		m_nErrNo=8;		//缺少保留字“ begin ”!
		m_nErrAddr=m_nCur;
		return false;
	}

	m_nCur++;

	if (!YuJuChuan())  //语句串
	{	
		return false;
	}
//cout<<m_cifa[m_nCur]->szText<<endl;
//cout<<m_cifa[m_nCur+1]->szText<<endl;
//cout<<m_cifa[m_nCur+2]->szText<<endl;
	if( m_cifa[m_nCur]->nType !=7)  //end
	{//cout<<m_cifa[m_nCur]->szText<<endl;
		m_nErrNo=10;	//缺少保留字“ end ”!
		m_nErrAddr=m_nCur;
		return false;
	}

	m_nCur++;

	return true;
}


/******************************************* 
* 函数名:    GuanXiBiaoDaShi
* 功能描述:   关系表达式 (protected)
* 返回值:    void
********************************************/
bool CFenXi::GuanXiBiaoDaShi()
{
	if (!BiaoDaShi())  //表达式
		return false;

	if (!GuanXi())	//关系
		return false;

	if (!BiaoDaShi())	//表达式
		return false;

	return true;
}

/******************************************** 
* 函数名:    GuanXi
* 功能描述:   关系   (protected)
* 返回值:    void
*********************************************/
bool CFenXi::GuanXi()
{

	switch (m_cifa[m_nCur]->nType)
	{
	case 23:	//<
	case 24:	//<=
	case 25:	//>
	case 26:	//>=
	case 27:	//=
	case 28:	//<>
		break;

	default:

⌨️ 快捷键说明

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