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

📄 morpheme.cpp

📁 词法语法语义编译器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
 *
 * @param  ch		给定的开始字符
 *
 */
bool CMorpheme::RecogChar(char ch)
{
	bool returnValue=true;

	CString word="";
	char charGet=GetChar();
	while (charGet!='\'' && charGet!=-1)
	{
		word+=charGet;
		charGet=GetChar();
	}

	if (charGet==-1)
	{
		AddError(m_rowCount,m_colsCount-word.GetLength(),"字符常数未结束!");
		returnValue=false;
	}

	if (strlen(word)!=0)
	{
		//添加token串
		unsigned id;
		//字符常数种别码
		id=this->FindKeyId("constchar");
		//入口地址
		unsigned entry=this->LookUp((LPCTSTR)word,Char);
		//添加token
		this->AddToken(id,entry);
	}
	return returnValue;
}

/**
 * 开始识别注释
 *
 * @param  ch		给定的开始字符
 *
 */
bool CMorpheme::HandleCom(char ch)
{
	bool returnValue=true;
	char charGet=GetChar();
	char charGet2;

	//是否为'/'
	if (charGet!='*')
	{
		if (charGet!=-1) 
		{
			m_colsCount--;
		}
		unsigned id=FindKeyId("/");
		AddToken(id,0);
	}
	else
	{
		unsigned int intRows=this->m_rowCount;
		unsigned int intCols=this->m_colsCount-2;

		charGet=GetCharNoNULL();
		if (charGet==-1)
		{
			//文件结束
			AddError(intRows,intCols,"注释未结束!");
			returnValue=false;
		}
		else
		{
			charGet2=GetChar();
			while(!(charGet2=='/' && charGet=='*'))
			{
				if (charGet2!=-1) this->m_colsCount--;
				charGet=GetCharNoNULL();
				if (charGet==-1)
				{
					//文件结束
					AddError(intRows,intCols,"注释未结束!");
					returnValue=false;
					break;
				}
				charGet2=GetChar();
			}
		}
	}

	return returnValue;
}

/**
 * 根据给定的字符进行相应的识别
 *
 * @param  ch		给定的开始字符
 *
 */
void CMorpheme::Sort(char ch)
{
	if (('a'<=ch && ch<='z') || ('A'<=ch && ch<='Z'))
	{
		this->RecogId(ch);						//识别标识符
	}
	else if (ch=='/')
	{
		this->HandleCom(ch);					//识别注释和'/'号
	}
	else if (ch=='\'')
	{
		this->RecogChar(ch);					//识别字符常数
	}
	else if ('0'<=ch && ch<='9')
	{
		this->RecogDigit(ch);					//识别数字常数
	}
	else
	{
		this->RecogDel(ch);						//识别界限符
	}
}

/**
 * 查添符号表
 *
 * @param  word		已经识别出的字符串
 * @param  type     符号串的类型
 *
 */
unsigned int CMorpheme::LookUp(const char *word,::SType type)
{
	unsigned int entry=-1;
	unsigned int nameStart=-1;
	unsigned int i,j;
	int start,len;
	char str[MAXLINE];
	double value;

	switch(type)
	{
	case Identifier:
	case Char:
		nameStart=-1;
		for (i=0;i<m_pSymbolTable->intSubTableLen;i++)
		{
			if (m_pSymbolTable->sSubTable[i].type==type)
			{
				start=m_pSymbolTable->sSubTable[i].name.headp;
				len=m_pSymbolTable->sSubTable[i].name.length;
				for (j=start;j<len+start;j++)
				{
					str[j-start]=m_pSymbolTable->stringTable[j];
				}
				str[j-start]='\0';
				if (strcmp(str,word)==0)
				{
					//已经存在
					nameStart=start;
					entry=i;//记录入口地址
					break;
				}
			}
		}		
		if (entry==-1)
		{
			//空间是否满足
			this->EnLageSTable(word);
			//添加
			strcpy(m_pSymbolTable->stringTable+m_pSymbolTable->intTableLen,word);
			nameStart=m_pSymbolTable->intTableLen;
			m_pSymbolTable->intTableLen+=strlen(word);

			m_pSymbolTable->sSubTable[m_pSymbolTable->intSubTableLen].type=type;
			m_pSymbolTable->sSubTable[m_pSymbolTable->intSubTableLen].name.headp=nameStart;
			m_pSymbolTable->sSubTable[m_pSymbolTable->intSubTableLen].name.length=strlen(word);
			m_pSymbolTable->sSubTable[m_pSymbolTable->intSubTableLen].addr=NULL;			
			entry=m_pSymbolTable->intSubTableLen;
			m_pSymbolTable->intSubTableLen++;
		}
		return entry+1;
		break;
	case Real:
	case Integer:
		value=atof(word);
		for (i=0;i<m_pSymbolTable->intSubTableLen;i++)
		{
			if ((m_pSymbolTable->sSubTable[i].type==type)&&(value==m_pSymbolTable->sSubTable[i].val))
			{
				//记录入口地址
				entry=i;
				break;
			}
		}		
		if (entry==-1)
		{
			//空间是否满足
			this->EnLageSTable("");
			//添加			
			m_pSymbolTable->sSubTable[m_pSymbolTable->intSubTableLen].type=type;
			m_pSymbolTable->sSubTable[m_pSymbolTable->intSubTableLen].name.headp=0;
			m_pSymbolTable->sSubTable[m_pSymbolTable->intSubTableLen].name.length=0;
			m_pSymbolTable->sSubTable[m_pSymbolTable->intSubTableLen].val=value;
			m_pSymbolTable->sSubTable[m_pSymbolTable->intSubTableLen].addr=NULL;
			entry=m_pSymbolTable->intSubTableLen;
			m_pSymbolTable->intSubTableLen++;
		}
		return entry+1;
		break;
	}
	return NULL;
}

/**
 * 对符号表进行扩容
 *
 * @param  str		当前要插入符号表中的字符串
 *
 */
bool CMorpheme::EnLageSTable(const char *str)
{
	PSTable pSTable=new STable;

	if (pSTable==NULL)
	{
		::AfxMessageBox("系统分配空间失败!",MB_ICONWARNING | MB_OK);
		return false;
	}

	if (m_pSymbolTable->intSubTableLen+strlen(str)>=m_pSymbolTable->intSubTableSize)
	{		
		//扩充子符号表
		pSTable->intSubTableSize=m_pSymbolTable->intSubTableSize+100;
		pSTable->sSubTable=new SSubTable[pSTable->intSubTableSize];
		if (pSTable->sSubTable==NULL)
		{
			::AfxMessageBox("系统分配空间失败!",MB_ICONWARNING | MB_OK);
			return false;
		}
		//复制
		for (unsigned int i=0;i<m_pSymbolTable->intSubTableSize;i++)
		{
			pSTable->sSubTable[i]=m_pSymbolTable->sSubTable[i];
		}
		//释放空间
		delete m_pSymbolTable->sSubTable;
		//赋值
		m_pSymbolTable->intSubTableSize=pSTable->intSubTableSize;
		m_pSymbolTable->sSubTable=pSTable->sSubTable;
	}

	if (m_pSymbolTable->intTableLen==m_pSymbolTable->intTableSize)
	{
		//扩充字符串表
		pSTable->intTableSize=m_pSymbolTable->intTableSize+100;
		pSTable->stringTable=new char[pSTable->intTableSize];
		if (pSTable->stringTable==NULL)
		{
			::AfxMessageBox("系统分配空间失败!",MB_ICONWARNING | MB_OK);
			return false;
		}
		//复制
		for (unsigned int i=0;i<m_pSymbolTable->intTableSize;i++)
		{
			pSTable->stringTable[i]=m_pSymbolTable->stringTable[i];
		}
		//释放空间
		delete m_pSymbolTable->stringTable;
		//赋值
		m_pSymbolTable->intTableSize=pSTable->intTableSize;
		m_pSymbolTable->stringTable=pSTable->stringTable;
	}

	delete pSTable;
	return true;
}

/**
 * 进行词法分析
 *
 * @param  strSourceFile		源程序文件路径
 *
 */
bool CMorpheme::Morpheme(CString strSourceFile/*=""*/)
{
	char charGet;

	//设置源程序文件路径
	if (strSourceFile!="")	
		this->m_strSourceFile=strSourceFile;
	else if (this->m_strSourceFile=="")
	{
		::AfxMessageBox("缺少源程序文件路径!",MB_ICONWARNING | MB_OK);
		return false;
	}

	//初始化:符号表,字符串表,token串表,行、列计数器
	if (!this->Init()) return false;
	//打开源文件
	if (!OpenSource()) return false;
	//开始词法分析
	int eoflg=this->ReadLine();
	//文件为空或读取失败
	if (eoflg!=1) return false;

	while ((charGet=this->GetCharNoNULL())!=-1)
	{		
		this->Sort(charGet);
	}
	//关闭源文件
	this->CloseSource();

	//一些后处理
	//SaveAll();

	return true;
}

/**
 * 分步进行词法分析
 *
 * @param  pToken				token引用
 * @param  strSourceFile		源程序文件路径
 *
 */
bool CMorpheme::StepMorpheme(PTokenNode &pToken,CString strSourceFile/*=""*/)
{
	char charGet;
	PTokenNode rearToken;
	pToken=NULL;
	
	if (!m_bStepOn)
	{
		//设置源程序文件路径
		if (strSourceFile!="")	
			this->m_strSourceFile=strSourceFile;
		else if (this->m_strSourceFile=="")
		{
			::AfxMessageBox("缺少源程序文件路径!",MB_ICONWARNING | MB_OK);
			return false;
		}
		
		//初始化:符号表,字符串表,token串表,行、列计数器
		if (!this->Init()) return false;
		//打开源文件
		if (!OpenSource()) return false;
		//开始词法分析
		int eoflg=this->ReadLine();
		//文件为空或读取失败
		if (eoflg!=1) return false;

		m_bStepOn=true;		
	}

	//单步词法分析
	rearToken=this->m_rearToken;
	do
	{
		if ((charGet=this->GetCharNoNULL())!=-1)
		{		
			this->Sort(charGet);
			pToken=m_rearToken;
		}
		else
		{
			m_bStepOn=false;
			pToken=NULL;
			break;
		}
	}while(rearToken==this->m_rearToken);
	
	if (!m_bStepOn)
	{
		//关闭源文件
		this->CloseSource();
		pToken=NULL;
	}

	return m_bStepOn;
}

/**
 * 获取当前行
 *
 * @return  unsigned int		当前行
 *
 */
unsigned int CMorpheme::GetCurRow()
{
	return this->m_rowCount;
}

/**
 * 获取当前列
 *
 * @return  unsigned int		当前列
 *
 */
unsigned int CMorpheme::GetCurCol()
{
	return this->m_colsCount;
}

CString CMorpheme::IntoStr(unsigned int num)
{
	char a;
	CString str;
	str.Empty();
	BOOL sign=FALSE;
    for(int i=4;i>-1;i--)
	{
		int div=1;
		for(int j=0;j<i;j++)
		{div=div*10;}
		int t=num/div;
		num=num%div;
		if(t!=0||sign)
		{a=48+t;
		str=str+a;
		sign=TRUE;}
	}
	str=str+'\0';
	return str;
}

void CMorpheme::SaveAll()
{
	/*
	char str[100];
	PTokenNode token;
	PSTable sTable;
	PErrorNode error;
	CString sfile;
	FILE* fpout;
	CMainFrame* pMainFrame=(CMainFrame*)AfxGetApp()->m_pMainWnd;	

	sfile=fileRoot+"token.dat";
	fpout=fopen(sfile.GetBuffer(0),"w");
	if (!fpout)
	{
		::AfxMessageBox("系统错误!");
		return;
	}
	else
	{
		fprintf(fpout,"%s\t(%s,%s)\n\n","标识符或数值","种别码","符号表入口");
		token=pMainFrame->pTokenFile;
		sTable=pMainFrame->m_pSymbolTable;
		int start,end;
		//写token
		while (token->next!=NULL)
		{
			token=token->next;	
			if (token->strId!=0)
			{				
				end=start=sTable->sSubTable[token->strId-1].name.headp;
				end+=sTable->sSubTable[token->strId-1].name.length;
				if (end==start)
				{
					if (sTable->sSubTable[token->strId-1].type==Real)
					{
						fprintf(fpout,"%f\t(%ld,%ld)\n",sTable->sSubTable[token->strId-1].val,token->keycode,token->strId);
					}
					else
					{
						fprintf(fpout,"%ld\t(%ld,%ld)\n",(long)sTable->sSubTable[token->strId-1].val,token->keycode,token->strId);
					}
				}
				else
				{
					for (int i=start;i<end;i++)
					{
						str[i-start]=sTable->stringTable[i];
					}
					str[i-start]='\0';
					fprintf(fpout,"%s\t(%ld,%ld)\n",str,token->keycode,token->strId);
				}
			}
			else
			{
				fprintf(fpout,"%s\t(%ld,%c)\n",pMainFrame->m_pWordCode[token->keycode],token->keycode,'_');
			}
		}
		fclose(fpout);
	}
	//写符号表
	sfile=fileRoot+"symboltable.dat";
	fpout=fopen(sfile.GetBuffer(0),"w");
	if (!fpout)
	{
		::AfxMessageBox("系统错误!");
		return;
	}
	else
	{
		fprintf(fpout,"%s\t(%s,%s)\t%s\n\n","符号串类型","开始地址","长度","值");
		sTable=pMainFrame->m_pSymbolTable;
		for (int i=0;i<sTable->intSubTableLen;i++)
		{
			if (sTable->sSubTable[i].type==Char || sTable->sSubTable[i].type==Identifier)
			{
				fprintf(fpout,"%s\t\t(%ld,%ld)\n",this->TypeToString(sTable->sSubTable[i].type),
											  sTable->sSubTable[i].name.headp,
											  sTable->sSubTable[i].name.length);
			}
			else if (sTable->sSubTable[i].type==Real)
			{
				fprintf(fpout,"%s\t\t(%ld,%ld)\t\t%f\n",this->TypeToString(sTable->sSubTable[i].type),
											  sTable->sSubTable[i].name.headp,
											  sTable->sSubTable[i].name.length,
											  sTable->sSubTable[i].val);
			}
			else if (pSTable->sSubTable[i].type==Integer)
			{
				fprintf(fpout,"%s\t\t(%ld,%ld)\t\t%ld\n",this->TypeToString(sTable->sSubTable[i].type),
											  sTable->sSubTable[i].name.headp,
											  sTable->sSubTable[i].name.length,
											  (long)sTable->sSubTable[i].val);
			}
		}

		if (sTable->intTableLen!=0)
		{
			fprintf(fpout,"\n符号表:\n\n");
			fprintf(fpout,"%s\n",sTable->stringTable);
		}

		fclose(fpout);
	}

	//写符号表
	sfile=fileRoot+"error.dat";
	fpout=fopen(sfile.GetBuffer(0),"w");
	if (!fpout)
	{
		::AfxMessageBox("系统错误!");
		return;
	}
	else
	{
		fprintf(fpout,"行,列\t错误描述\n\n");
		error=pMainFrame->m_pErrorCollection;
		while (error->next!=NULL)
		{
			error=error->next;
			fprintf(fpout,"%ld行,%ld列\t%s\n",error->intRows,error->intCols,error->description);
		}

		fclose(fpout);
	}
	*/
}

//
char *CMorpheme::TypeToString(SType type)
{
	switch(type)
	{
	case Identifier:
		return "Identifier";
		break;
	case Char:
		return "Char";
		break;
	case Real:
		return "Real";
		break;
	case Integer:
		return "Integer";
		break;
	}
	return "";
}

CMorpheme::~CMorpheme()
{

}

⌨️ 快捷键说明

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