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

📄 cfenxi.cpp

📁 本学期编译课程需要实现L语言
💻 CPP
字号:
// CFenXi.cpp: implementation of the CFenXi class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "Lojo.h"
#include "CFenXi.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#define WORDLEN 20
#define NUMLEN   8
#endif
CFenXi::CFenXi(){}
CFenXi::~CFenXi(){}
/*================================================================ 
* 函数名:    CiFaFenXi
* 功能描述:   词法分析 (public)
* 返回值:    void
================================================================*/
void CFenXi::CiFaFenXi(){
	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<WORDLEN-1)				//标志符的长度为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;
			BOOL isreal=false;
			while (1)
			{
				if (k<=NUMLEN) //
					token[k++]=m_str[n++];
				else
				{
					error=true;
					n++;
				}				
				if (!isdigit(m_str[n])){
					if(m_str[n]=='.') isreal=true;//实数
					else 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;
				if(isreal)	m_cifa[m_n]->nType=3; //实数
				else 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 ')':
			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++;

	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; //未找到
}
/*================================================================ 
* 函数名:    init
* 功能描述:   用于初始化关键字表和错误信息表   (protected)
* 返回值:    void
================================================================*/
void CFenXi::init()
{
	strcpy(m_szKW[0],"");
 	strcpy(m_szKW[1],"");//标识符  
	strcpy(m_szKW[2],"");//整数
	strcpy(m_szKW[3],"");//实数
	strcpy(m_szKW[4],"TRUE"); //布尔值
	strcpy(m_szKW[5],"FALSE");

	strcpy(m_szKW[6],"CONST"); //变量类型
	strcpy(m_szKW[7],"INTEGER"); 
	strcpy(m_szKW[8],"REAL");    
	strcpy(m_szKW[9],"BOOLEAN");
	strcpy(m_szKW[10],"ARRAY");

	strcpy(m_szKW[11],"PROGRAM"); //程序架构
	strcpy(m_szKW[12],"FUNCTION");
	strcpy(m_szKW[13],"RETURN");

	strcpy(m_szKW[14],"BEGIN"); //起始结束
	strcpy(m_szKW[15],"END");

	strcpy(m_szKW[16],"IF");//条件
	strcpy(m_szKW[17],"THEN");
	strcpy(m_szKW[18],"ELSE");

	strcpy(m_szKW[19],"WHILE"); //循环1
	strcpy(m_szKW[20],"DO");
	
	strcpy(m_szKW[21],"FOR");//循环2
	strcpy(m_szKW[22],"TO");

	strcpy(m_szKW[23],"REPEAT");//循环3
	strcpy(m_szKW[24],"UNTIL");

	strcpy(m_szKW[25],"READ"); //读写
	strcpy(m_szKW[26],"WRITE");

    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_szKW[50],"*/");	
    
	strcpy(m_szTP[0],"未知    ");
	strcpy(m_szTP[1],"标识符 ");
	strcpy(m_szTP[2],"整数    ");
	strcpy(m_szTP[3],"实数    ");
	strcpy(m_szTP[4],"布尔数 ");
	strcpy(m_szTP[5],"关键字 ");
	strcpy(m_szTP[6],"运算符 ");
	strcpy(m_szTP[7],"分割符 ");
	
	strcpy(m_szErrMsg[0],"正确!");
	strcpy(m_szErrMsg[1],"数字位数过长!");
	strcpy(m_szErrMsg[2],"非法字符!");
	strcpy(m_szErrMsg[3],"缺少关键字“ program ”!");
	strcpy(m_szErrMsg[4],"program 后缺少标识符!");
	strcpy(m_szErrMsg[5],"缺少“ ; ”符号!");
	strcpy(m_szErrMsg[6],"缺少程序结束符“ . ”符号!");
	strcpy(m_szErrMsg[7],"缺少《程序体》,应为 begin,integer,real,function");
	strcpy(m_szErrMsg[8],"缺少保留字“ begin ”!");
	strcpy(m_szErrMsg[9],"缺少《语句》,应为 begin,ID,if,while,call");
	strcpy(m_szErrMsg[10],"缺少保留字“ end ”!");
	strcpy(m_szErrMsg[11],"缺少《声明》,应为 integer,real,function");
	strcpy(m_szErrMsg[12],"缺少保留字 integer 或 real!");
	strcpy(m_szErrMsg[13],"function 后缺少标识符!");
	strcpy(m_szErrMsg[14],"变量声明后缺少标识符!");
	strcpy(m_szErrMsg[15],"缺少保留字“ function ”!");
	strcpy(m_szErrMsg[16],"缺少 “ ( ”符号!");
	strcpy(m_szErrMsg[17],"缺少 “ ) ”符号!");
	strcpy(m_szErrMsg[18],"缺少形参标识符 !");
	strcpy(m_szErrMsg[19],"缺少 “ : ”符号!");
	strcpy(m_szErrMsg[20],"缺少标识符!");
	strcpy(m_szErrMsg[21],"缺少赋值符号“ := ”!");
	strcpy(m_szErrMsg[22],"缺少保留字“ if ”!");
	strcpy(m_szErrMsg[23],"缺少保留字“ then ”!");
	strcpy(m_szErrMsg[24],"缺少保留字“ while ”!");
	strcpy(m_szErrMsg[25],"缺少保留字“ do ”!");
	strcpy(m_szErrMsg[26],"缺少保留字“ call ”!");
	strcpy(m_szErrMsg[27],"缺少被调过程名标识符!");
	strcpy(m_szErrMsg[28],"缺少《因子》,应为 (,ID,NUMBER");
	strcpy(m_szErrMsg[29],"缺少《布尔表达式》,应为 ~,(,ID,NUMBER");
	strcpy(m_szErrMsg[30],"缺少《关系》!");
	strcpy(m_szErrMsg[31],"变量名不能和过程名相同!");
	strcpy(m_szErrMsg[32],"标识符重复声明!");
	strcpy(m_szErrMsg[33],"未声明标识符!");
	strcpy(m_szErrMsg[34],"不能直接引用过程名!");
	strcpy(m_szErrMsg[35],"不能从real转换为integer类型!");
	strcpy(m_szErrMsg[36],"不能用常数作实参!");
	strcpy(m_szErrMsg[37],"变参应为变量!");
	strcpy(m_szErrMsg[38],"实参个数不足!");
	strcpy(m_szErrMsg[39],"只有integer和integer才能比较!");
	strcpy(m_szErrMsg[40],"不能这样调用过程!");
	strcpy(m_szErrMsg[41],"");
	strcpy(m_szErrMsg[42],"");
	strcpy(m_szErrMsg[43],"");
	strcpy(m_szErrMsg[96],"源程序结束符 end. 后还有多余内容!");
	strcpy(m_szErrMsg[97],"语法错误太多,终止语法分析!");
	strcpy(m_szErrMsg[98],"源程序不正常结束!");
	strcpy(m_szErrMsg[99],"内存不足!词法分析终止!");
}

⌨️ 快捷键说明

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