📄 morpheme.cpp
字号:
// Morpheme.cpp: implementation of the Morpheme class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "scanner.h"
#include "Morpheme.h"
#include "MainFrm.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
/**
* 词法分析构造函数
*
* @param pWordCode 字符表数组
* @param pTokenFile token串头指针
* @param pSymbolTable 符号表头指针
* @param pErrorCollection 错误信息头指针
*
*/
CMorpheme::CMorpheme(const char *pWordCode[],
PTokenNode pTokenFile,
PSTable pSymbolTable,
PErrorNode pErrorCollection)
{
m_bStepOn=false;
this->m_strSourceFile="";
this->m_pTokenFile=pTokenFile;
this->m_pSymbolTable=pSymbolTable;
this->m_pErrorCollection=pErrorCollection;
for (int i=0;i<KEYWORDCOUNT+1;i++)
{
this->m_pWordCode[i]=pWordCode[i];
}
}
/**
* 词法分析构造函数
*
* @param pWordCode 字符表数组
* @param pTokenFile token串头指针
* @param pSymbolTable 符号表头指针
* @param pErrorCollection 错误信息头指针
* @param strSourceFile 源文件路径
*
*/
CMorpheme::CMorpheme(const char *pWordCode[],
PTokenNode pTokenFile,
PSTable pSymbolTable,
PErrorNode pErrorCollection,
CString strSourceFile)
{
m_bStepOn=false;
this->m_strSourceFile=strSourceFile;
this->m_pTokenFile=pTokenFile;
this->m_pSymbolTable=pSymbolTable;
this->m_pErrorCollection=pErrorCollection;
for (int i=0;i<KEYWORDCOUNT+1;i++)
{
this->m_pWordCode[i]=pWordCode[i];
}
}
/**
* 初始化各链表头部信息
*
*/
bool CMorpheme::Init()
{
m_pSymbolTable->intTableSize=100;
m_pSymbolTable->intTableLen=0;
m_pSymbolTable->sSubTable=new SSubTable[100];
if (m_pSymbolTable->sSubTable==NULL)
{
::AfxMessageBox("系统初始化失败!",MB_ICONWARNING | MB_OK);
return false;
}
m_pSymbolTable->intSubTableSize=100;
m_pSymbolTable->intSubTableLen=0;
m_pSymbolTable->stringTable=new char[100];
if (m_pSymbolTable->stringTable==NULL)
{
::AfxMessageBox("系统初始化失败!",MB_ICONWARNING | MB_OK);
return false;
}
m_pTokenFile->next=NULL;
this->m_rearToken=m_pTokenFile;
m_pErrorCollection->next=NULL;
this->m_rearError=m_pErrorCollection;
// 初始化 行,列计数
this->m_rowCount=0;
this->m_colsCount=0;
return true;
}
/**
* 打开源程序文件
*
*/
bool CMorpheme::OpenSource()
{
this->m_finSource.open(m_strSourceFile);
if (m_finSource.fail())
{
::AfxMessageBox("源程序文件打开失败!",MB_ICONWARNING | MB_OK);
CloseSource();
return false;
}
return true;
}
/**
* 关闭源程序文件
*
*/
void CMorpheme::CloseSource()
{
this->m_finSource.close();
}
/**
* 从源程序文件中度曲一行
*
*/
int CMorpheme::ReadLine()
{
if (!m_finSource.eof())
{
this->m_colsCount=0; //列清0
this->m_rowCount++; //行加一
m_finSource.getline(m_strLine,MAXLINE);
m_strLine[MAXLINE-1]='\0';
return 1;
}
else
{
this->m_colsCount=0; //列清0
this->m_strLine[0]='\0';
return 0;
}
return -1;
}
/**
* 从当前行中读取一个非空字符
*
*/
char CMorpheme::GetCharNoNULL()
{
int readFlg;
while (m_strLine[m_colsCount]==' ' || m_strLine[m_colsCount]=='\t' || m_strLine[m_colsCount]=='\0')
{
if (m_strLine[m_colsCount]=='\0')
{
readFlg=ReadLine();
if (readFlg==-1)
{
AfxMessageBox("系统错误!",MB_ICONWARNING | MB_OK);
return -1;
}
if (readFlg==0)
{
return -1;
}
m_colsCount--;
}
m_colsCount++;
}
m_colsCount++;
return m_strLine[m_colsCount-1];
}
/**
* 从当前行中读取一个字符
*
*/
char CMorpheme::GetChar()
{
if (this->m_strLine[m_colsCount]=='\0')
{
return -1;
}
m_colsCount++;
if (m_strLine[m_colsCount-1]==' ' || m_strLine[m_colsCount-1]=='\t')
{
return -2;
}
return m_strLine[m_colsCount-1];
}
/**
* 判断当前给定的字符串是否是关键字
*
* @param str 给定的字符串
*
*/
unsigned int CMorpheme::IsKeyId(const char *str)
{
for (int i=1;i<KEYWORDCOUNT;i++)
{
if (strcmp(str,m_pWordCode[i])==0)
{
return i;
}
}
return 0;//不存在
}
/**
* 查找当前给定的关键字在字符表中的索引号
*
* @param str 给定的字符串
*
*/
unsigned int CMorpheme::FindKeyId(const char *str)
{
if (strcmp(str,"constchar")==0)
{//字符常数
return 32;
}
if (strcmp(str,"constfloat")==0)
{//实常数
return 33;
}
if (strcmp(str,"constint")==0)
{//整常数
return 34;
}
if (strcmp(str,"identifier")==0)
{//标识符
return 40;
}
for (int i=1;i<KEYWORDCOUNT;i++)
{
if (strcmp(str,m_pWordCode[i])==0)
{
return i;
}
}
return 0;//不存在
}
/**
* 开始识别标示符
*
* @param ch 给定的开始字符
*
*/
bool CMorpheme::RecogId(char ch)
{
bool returnValue=true;
CString word="";
word+=ch;
char charGet=GetChar();
while (('0'<=charGet && charGet<='9') || ('a'<=charGet && charGet<='z') || ('A'<=charGet && charGet<='Z'))
{
word+=charGet;
charGet=GetChar();
}
unsigned keyId;
if (charGet!=-2 && charGet!=-1)
{
char chch[2];
chch[0]=charGet;
chch[1]='\0';
keyId=IsKeyId(chch);
if (keyId!=0)
{
this->m_colsCount--;//列计数-1
}
else
{//非法字符
AddError(this->m_rowCount,this->m_colsCount,"非法字符!");
returnValue=false;
}
}
keyId=IsKeyId((LPCTSTR)word);
if (keyId > 0)
{//关键字
//添加token
this->AddToken(keyId,0);
}
else
{
//标识符种别码
unsigned id=this->FindKeyId("identifier");
//入口地址
unsigned entry=this->LookUp((LPCTSTR)word,Identifier);
//添加token
this->AddToken(id,entry);
}
return returnValue;
}
/**
* 添加错误信息
*
* @param rows 行号
* @param cols 列号
* @param description 错误描述信息
*
*/
bool CMorpheme::AddError(const char *description,unsigned int rows/*=0*/,unsigned int cols/*=0*/)
{
return AddError(rows,cols,description);
}
/**
* 添加错误信息
*
* @param rows 行号
* @param cols 列号
* @param description 错误描述信息
*
*/
bool CMorpheme::AddError(unsigned int rows,unsigned int cols,const char *description)
{
m_rearError->next=new ErrorNode;
char *ch=new char[strlen(description)+1];
if (m_rearError->next==NULL || ch==NULL)
{
AfxMessageBox("内存分配失败!",MB_ICONWARNING | MB_OK);
return false;
}
m_rearError=m_rearError->next;
m_rearError->intCols=cols;
m_rearError->intRows=rows;
strcpy(ch,description);
m_rearError->description=ch;
m_rearError->next=NULL;
return true;
}
/**
* 添加token信息
*
* @param keycode 类型种别码
* @param strId 自身值
*
*/
bool CMorpheme::AddToken(unsigned char keycode,unsigned int strId)
{
m_rearToken->next=new TokenNode;
if (m_rearToken->next==NULL)
{
AfxMessageBox("内存分配失败!",MB_ICONWARNING | MB_OK);
return false;
}
m_rearToken=m_rearToken->next;
m_rearToken->strId=strId;
m_rearToken->keycode=keycode;
m_rearToken->next=NULL;
return true;
}
/**
* 删除token字
*
* @param pToken 给定删除token字
*
*/
bool CMorpheme::DeleteToken(PTokenNode pToken)
{
PTokenNode pPreToken=NULL,pCurToken=NULL;
if (this->m_pTokenFile->next==NULL) return false;
if (pToken==NULL) return true;
pPreToken=this->m_pTokenFile;
pCurToken=this->m_pTokenFile->next;
while (pCurToken!=NULL && pCurToken!=pToken)
{
pPreToken=pCurToken;
pCurToken=pCurToken->next;
}
if (pToken==pCurToken)
{
pPreToken->next=pCurToken->next;
if (pCurToken==this->m_rearToken)
{
this->m_rearToken=pPreToken;
this->m_rearToken->next=NULL;
}
delete (pCurToken);
}
else
{
return false;
}
return true;
}
/**
* 开始识别界限符
*
* @param ch 给定的开始字符
*
*/
bool CMorpheme::RecogDel(char ch)
{
unsigned int keyId;
char ch2;
char chch[3]={'\0','\0','\0'};
chch[0]=ch;
switch(ch)
{
case '(':
case ')':
case '*':
case '+':
case ',':
case '-':
case ';':
case '[':
case ']':
case '=':
//单字符界限符
break;
case '.':
ch2=this->GetChar();
if (ch2=='.')
{
chch[1]='.';
}
else if (ch2!=-1)
{
this->m_colsCount--;
}
break;
case ':':
ch2=this->GetChar();
if (ch2=='=')
{
chch[1]='=';
}
else if (ch2!=-1)
{
this->m_colsCount--;
}
break;
case '<':
ch2=this->GetChar();
if (ch2=='=' || ch2=='>')
{
chch[1]=ch2;
}
else if (ch2!=-1)
{
this->m_colsCount--;
}
break;
case '>':
ch2=this->GetChar();
if (ch2=='=')
{
chch[1]='=';
}
else if (ch2!=-1)
{
this->m_colsCount--;
}
break;
default:
AddError(this->m_rowCount,this->m_colsCount,"非法字符!");
return false;
break;
}
keyId=this->FindKeyId(chch);
this->AddToken(keyId,0);
return true;
}
/**
* 开始识别数字常数
*
* @param ch 给定的开始字符
*
*/
bool CMorpheme::RecogDigit(char ch)
{
CString word="";
word+=ch;
char charGet=GetChar();
bool firstDot=true;
::SType digitType=Integer;
while (('0'<=charGet && charGet<='9') || (charGet=='.'))
{
if (charGet=='.')
{
//当读入两个'.'时,出错
if (!firstDot) break;
char ch2=this->GetChar();
if (ch2=='.')
{
//整数常数识别成功;识别了标识符 ..
this->m_colsCount--;
break;
}
else if (ch2==-2 || ch2==-1)
{
//实数常数识别成功
digitType=Real;
break;
}
else
{
this->m_colsCount--;
firstDot=false;
}
}
word+=charGet;
charGet=GetChar();
}
//列计数-1
if (charGet!=-1) this->m_colsCount--;
if (!firstDot) digitType=Real;
unsigned id;
//数字常数种别码
if (digitType==Real)
{
id=this->FindKeyId("constfloat");
}
else
{
id=this->FindKeyId("constint");
}
//入口地址
unsigned entry=this->LookUp((LPCTSTR)word,digitType);
//添加token
this->AddToken(id,entry);
return true;
}
/**
* 开始识别字符常数
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -