📄 semantic.cpp
字号:
// Semantic.cpp: implementation of the CSemantic class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "scanner.h"
#include "Semantic.h"
#include "Parsing.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 错误信息头指针
*
*/
CSemantic::CSemantic(const char *pWordCode[],
PTokenNode pTokenFile,
PSTable pSymbolTable,
PFSymbol pFSymbol,
PErrorNode pErrorCollection)
{
m_strSourceFile="";
m_bUseCurToken=true;
m_pCurToken=NULL;
m_pFSymbol=pFSymbol;
this->m_pMorpheme=new CMorpheme(pWordCode,pTokenFile,pSymbolTable,pErrorCollection);
this->m_pSymbolTable=pSymbolTable;
for (int i=0;i<KEYWORDCOUNT+1;i++)
{
this->m_pWordCode[i]=pWordCode[i];
}
InitPFSymbol();
}
/**
* 语义分析构造函数
*
* @param pWordCode 字符表数组
* @param pTokenFile token串头指针
* @param pSymbolTable 符号表头指针
* @param pErrorCollection 错误信息头指针
* @param strSourceFile 源程序文件路径
*
*/
CSemantic::CSemantic(const char *pWordCode[],
PTokenNode pTokenFile,
PSTable pSymbolTable,
PFSymbol pFSymbol,
PErrorNode pErrorCollection,
CString strSourceFile)
{
m_strSourceFile=strSourceFile;
m_bUseCurToken=true;
m_pCurToken=NULL;
m_pFSymbol=pFSymbol;
this->m_pMorpheme=new CMorpheme(pWordCode,pTokenFile,pSymbolTable,pErrorCollection,strSourceFile);
this->m_pSymbolTable=pSymbolTable;
for (int i=0;i<KEYWORDCOUNT+1;i++)
{
this->m_pWordCode[i]=pWordCode[i];
}
InitPFSymbol();
}
/**
* 初始化四元式链
*
*/
void CSemantic::InitPFSymbol()
{
PFSymbol pFS=NULL;
if (this->m_pFSymbol->next!=NULL)
{
while (m_pFSymbol->next!=NULL)
{
pFS=m_pFSymbol->next;
m_pFSymbol->next=pFS->next;
delete pFS;
}
}
this->m_pFSymbol->next=new FSymbol;
m_pCurFS=m_pFSymbol->next;
m_pCurFS->no=1;
m_pCurFS->ag1=NULL;
m_pCurFS->ag2=NULL;
m_pCurFS->next=NULL;
m_pCurFS->result=NULL;
}
CSemantic::~CSemantic()
{
}
/**
* 获取下一个token字
*
* @param PTokenNode &pToken token字引用
*
* @return bool F:文件分析完毕
*
*/
bool CSemantic::GetNextToken(PTokenNode &pToken)
{
bool returnValue=true;
if (this->m_bUseCurToken)
{
returnValue=this->m_pMorpheme->StepMorpheme(m_pCurToken,this->m_strSourceFile);
}
pToken=this->m_pCurToken;
this->m_bUseCurToken=true;
return returnValue;
}
/**
* 当前获取的token字没被用
*
*/
void CSemantic::NoUseCurToken()
{
this->m_bUseCurToken=false;
}
/**
* 连接两个四元式链,链首以pFS2开始
*
* @param PFSymbol pFS1 四元式一
* @param PFSymbol pFS2 四元式二
*
* @return PFSymbol 连接链首指针
*
*/
PFSymbol CSemantic::Merg(PFSymbol pFS1,PFSymbol pFS2)
{
if (pFS2==NULL) return pFS1;
else
{
PFSymbol pFS=pFS2;
while (pFS->result!=NULL && pFS->result->type==PF && pFS->result->value.fSymbol!=NULL)
{
pFS=pFS->result->value.fSymbol;
}
if (pFS->result==NULL)
{
pFS->result=new FSAG;
pFS->result->des=NULL;
pFS->result->type=PF;
pFS->result->value.fSymbol=pFS1;
}
else
{
pFS->result->value.fSymbol=pFS1;
pFS->result->type=PF;
}
return pFS2;
}
}
/**
* 将nextFS填入pFS的第四个分量
*
* @param PFSymbol pFS 四元式一
* @param PFSymbol nextFS 四元式二
*
* @return bool 操作结果
*
*/
bool CSemantic::BackPatch(PFSymbol pFS,PFSymbol nextFS)
{
PFSymbol q,Q;
char ch[10];
Q=pFS;
while (Q!=NULL)
{
if (Q->result==NULL)
{
Q->result=new FSAG;
itoa(nextFS->no,ch,10);
Q->result->des=new char[strlen(ch)+1];
strcpy(Q->result->des,ch);
Q->result->type=PF;
Q->result->value.fSymbol=nextFS;
break;
}
else
{
if (Q->result->type!=PF) break;
q=Q->result->value.fSymbol;
itoa(nextFS->no,ch,10);
Q->result->des=new char[strlen(ch)+1];
strcpy(Q->result->des,ch);
Q->result->value.fSymbol=nextFS;
Q=q;
}
}
return true;
}
/**
* 获取当前要生成的四元式
*
*/
PFSymbol CSemantic::GetCurPFS()
{
return this->m_pCurFS;
}
/**
* 添加错误信息
*
* @param const char *description 错误信息描述
*
*/
void CSemantic::AddError(const char *description)
{
this->m_pMorpheme->AddError(description,this->m_pMorpheme->GetCurRow());
}
/**
* 翻译<AE>->i+i|i-i
*
* @param PTokenNode pToken token字
*
*/
PFSAG CSemantic::Ae(PTokenNode pToken)
{
char ch[10];EOP op;
PFSAG ag1=NULL,ag2=NULL;
PFSAG result=new FSAG;
result->des="Temp";
result->type=ST;
if (strcmp(this->m_pWordCode[pToken->keycode],"identifier")!=0 &&
strcmp(this->m_pWordCode[pToken->keycode],"constfloat")!=0 &&
strcmp(this->m_pWordCode[pToken->keycode],"constint")!=0)
{
this->AddError("赋值表达式错误!");
this->NoUseCurToken();
return NULL;
}
ag1=new FSAG;
if (strcmp(this->m_pWordCode[pToken->keycode],"identifier")==0)
{
ag1->des=this->GetIDName(pToken);
ag1->type=PT;
ag1->value.token=pToken;
}
else
{
itoa((int)this->m_pSymbolTable->sSubTable[pToken->strId-1].val,ch,10);
ag1->des=new char[strlen(ch)+1];
strcpy(ag1->des,ch);
ag1->type=ST;
ag1->value.value=this->m_pSymbolTable->sSubTable[pToken->strId-1].val;
}
GetNextToken(pToken);
if (strcmp(this->m_pWordCode[pToken->keycode],"+")!=0 &&
strcmp(this->m_pWordCode[pToken->keycode],"-")!=0)
{
this->NoUseCurToken();
Gencode(GetOP(":="),ag1,NULL,result);
return result;
}
op=GetOP(this->m_pWordCode[pToken->keycode]);
GetNextToken(pToken);
if (strcmp(this->m_pWordCode[pToken->keycode],"identifier")!=0 &&
strcmp(this->m_pWordCode[pToken->keycode],"constfloat")!=0 &&
strcmp(this->m_pWordCode[pToken->keycode],"constint")!=0)
{
this->AddError("赋值表达式错误!");
this->NoUseCurToken();
Gencode(GetOP(":="),ag1,NULL,result);
return result;
}
ag2=new FSAG;
if (strcmp(this->m_pWordCode[pToken->keycode],"identifier")==0)
{
ag2->des=this->GetIDName(pToken);
ag2->type=PT;
ag2->value.token=pToken;
}
else
{
itoa((int)this->m_pSymbolTable->sSubTable[pToken->strId-1].val,ch,10);
ag2->des=new char[strlen(ch)+1];
strcpy(ag2->des,ch);
ag2->type=ST;
ag2->value.value=this->m_pSymbolTable->sSubTable[pToken->strId-1].val;
}
Gencode(op,ag1,ag2,result);
return result;
}
/**
* 翻译<BE>-><BT>(or<BE>|e)
*
* @param PTokenNode pToken token字
* @param PFSymbol &pTC 真出口
* @param PFSymbol &pFC 假出口
*
*/
void CSemantic::Be(PTokenNode pToken,PFSymbol &pTC,PFSymbol &pFC)
{
PFSymbol btTC=NULL,btFC=NULL,beTC=NULL,beFC=NULL;
PTokenNode token=NULL;
const char *str=this->m_pWordCode[pToken->keycode];
if (strcmp(str,"not")==0 || strcmp(str,"(")==0 || strcmp(str,"identifier")==0)
{
Bt(pToken,btTC,btFC);
this->BackPatch(btFC,GetCurPFS());
this->GetNextToken(token);
if (strcmp(this->m_pWordCode[token->keycode],"or")==0)
{
this->GetNextToken(token);
Be(token,beTC,beFC);
pTC=this->Merg(btTC,beTC);
pFC=beFC;
}
else
{
pTC=btTC;
pFC=btFC;
this->NoUseCurToken();
}
}
else
{
this->AddError("条件表达式错误!");
this->NoUseCurToken();
}
}
/**
* 翻译<BT>-><BF>(and<BT>|e)
*
* @param PTokenNode pToken token字
* @param PFSymbol &pTC 真出口
* @param PFSymbol &pFC 假出口
*
*/
void CSemantic::Bt(PTokenNode pToken,PFSymbol &pTC,PFSymbol &pFC)
{
PFSymbol bfTC=NULL,bfFC=NULL,btTC=NULL,btFC=NULL;
PTokenNode token=NULL;
const char *str=this->m_pWordCode[pToken->keycode];
if (strcmp(str,"not")==0 || strcmp(str,"(")==0 || strcmp(str,"identifier")==0)
{
Bf(pToken,bfTC,bfFC);
BackPatch(bfTC,this->GetCurPFS());
GetNextToken(token);
if (strcmp(this->m_pWordCode[token->keycode],"and")==0)
{
GetNextToken(token);
Bt(token,btTC,btFC);
pFC=Merg(btFC,bfFC);
pTC=btTC;
}
else
{
pTC=bfTC;
pFC=bfFC;
this->NoUseCurToken();
}
}
else
{
this->AddError("条件表达式错误!");
this->NoUseCurToken();
}
}
/**
* 生成四元式
*
* @param EOP op 操作符
* @param PFSAG ag1 运算对象一
* @param PFSAG ag1 运算对象二
* @param PFSAG result 运算结果
*
*/
void CSemantic::Gencode(EOP op,PFSAG ag1,PFSAG ag2,PFSAG result)
{
PFSymbol pFS=new FSymbol;
pFS->next=NULL;
pFS->ag1=NULL;
pFS->ag2=NULL;
pFS->result=NULL;
m_pCurFS->op=op;
m_pCurFS->ag1=ag1;
m_pCurFS->ag2=ag2;
m_pCurFS->result=result;
this->m_pCurFS->next=pFS;
pFS->no=this->m_pCurFS->no+1;
this->m_pCurFS=pFS;
}
/**
* 获取pToken的标示名称
*
* @param PTokenNode pToken token字
*
*/
char *CSemantic::GetIDName(PTokenNode pToken)
{
if (strcmp(this->m_pWordCode[pToken->keycode],"identifier")==0)
{
unsigned int istart=this->m_pSymbolTable->sSubTable[pToken->strId-1].name.headp;
unsigned int ilen=this->m_pSymbolTable->sSubTable[pToken->strId-1].name.length;
char *str=new char[ilen+1];
for (int i=0;i<ilen;i++)
{
str[i]=this->m_pSymbolTable->stringTable[istart+i];
}
str[ilen]='\0';
return str;
}
else return NULL;
}
/**
* 翻译<BF>->not<BF>
* ->'('<BE>')'
* ->i(rop i|e)
*
* @param PTokenNode pToken token字
* @param PFSymbol &pTC 真出口
* @param PFSymbol &pFC 假出口
*
*/
void CSemantic::Bf(PTokenNode pToken,PFSymbol &pTC,PFSymbol &pFC)
{
PFSymbol bfTC=NULL,bfFC=NULL;
PTokenNode token=NULL;
const char *str=this->m_pWordCode[pToken->keycode];
if (strcmp(str,"not")==0)
{
GetNextToken(token);
Bf(token,bfTC,bfFC);
pTC=bfFC;
pFC=bfTC;
}
else if (strcmp(str,"(")==0)
{
GetNextToken(token);
Be(token,pTC,pFC);
GetNextToken(token);
if (strcmp(this->m_pWordCode[token->keycode],")")!=0)
{
this->AddError("缺少)");
this->NoUseCurToken();
}
}
else if (strcmp(str,"identifier")==0)
{
PFSAG pFSAG1=new FSAG;
pFSAG1->type=PT;
pFSAG1->value.token=pToken;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -