📄 morpheme.cpp
字号:
*
* @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 + -