📄 语义分析.txt
字号:
// analyze.cpp: implementation of the Canalyze class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "face.h"
#include "analyze.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
Canalyze::Canalyze()
{
/*scope栈的层数*/
Level=-1;
intPtr = NULL; /*该指针一直指向整数类型的内部表示*/
charPtr = NULL; /*该指针一直指向字符类型的内部表示*/
boolPtr = NULL; /*该指针一直指向布尔类型的内部表示*/
Error = false;
}
Canalyze::~Canalyze()
{
}
/*********************实用函数实现***************************/
/**********************************************************/
/**************** 符号表相关操作 **********************/
/**********************************************************/
/********************************************************/
/* 函数名 PrintFieldTable */
/* 功 能 打印纪录类型的域表 */
/* 说 明 */
/********************************************************/
void Canalyze::PrintFieldChain(fieldChain *currentP)
{
fprintf(listing,"\n--------------Field chain--------------------\n");
fieldChain *t=currentP;
while (t!=NULL)
{ /*输出标识符名字*/
fprintf(listing ,"%s: ",t->id );
/*输出标识符的类型信息*/
switch(t->UnitType->kind)
{case intTy : fprintf(listing ,"intTy "); break;
case charTy: fprintf(listing ,"charTy "); break;
case arrayTy: fprintf(listing ,"arrayTy "); break;
case recordTy:fprintf(listing ,"recordTy ");break;
default : fprintf(listing ,"error type! "); break;
}
fprintf(listing ,"off = %d\n",t->off);
t = t->Next;
}
}
/********************************************************/
/* 函数名 PrintOneLayer */
/* 功 能 打印符号表的一层 */
/* 说 明 有符号表打印函数PrintSymbTable调用 */
/********************************************************/
void Canalyze::PrintOneLayer(int level)
{
SymbTable *t= scope[level];
fprintf(listing,"\n-------SymbTable in level %d ---------\n",level);
while (t!=NULL)
{ /*输出标识符名字*/
fprintf(listing ,"%s: ",t->idName);
AttributeIR *Attrib = &(t->attrIR );
/*输出标识符的类型信息,过程标识符除外*/
if (Attrib->idtype!=NULL) /*过程标识符*/
switch(Attrib->idtype->kind)
{case intTy : fprintf(listing ,"intTy "); break;
case charTy: fprintf(listing ,"charTy "); break;
case arrayTy: fprintf(listing ,"arrayTy "); break;
case recordTy:fprintf(listing ,"recordTy ");break;
default : fprintf(listing ,"error type! "); break;
}
/*输出标识符的类别,并根据不同类型输出不同其它属性*/
switch(Attrib->kind)
{case typeKind :
fprintf(listing, "typekind "); break;
case varKind :
fprintf(listing, "varkind ");
fprintf(listing ,"Level = %d ", Attrib->More.VarAttr.level);
fprintf(listing ,"Offset= %d ", Attrib->More.VarAttr.off);
switch(Attrib->More.VarAttr.access)
{ case dir : fprintf(listing ,"dir "); break;
case indir: fprintf(listing ,"indir ");break;
default :fprintf(listing ,"errorkind "); break;
}
break;
case procKind:
fprintf(listing ,"funckind ");
fprintf(listing ,"Level= %d ",Attrib->More.ProcAttr.level);
fprintf(listing ,"Noff= %d ",Attrib->More.ProcAttr.nOff);
break;
default :fprintf(listing ,"error ");
}
fprintf(listing,"\n");
t = t->next;
}
}
/********************************************************/
/* 函数名 PrintSymbTable */
/* 功 能 打印生成的符号表 */
/* 说 明 */
/********************************************************/
void Canalyze::PrintSymbTable( )
{ /*层数从0开始*/
int level=0;
while (scope[level]!=NULL)
{ PrintOneLayer(level);
level++;
}
}
/***********************************************************/
/* 函数名 NewTable */
/* 功 能 创建当前空符号表 */
/* 说 明 遇到新的无声明的标识符时创建新的空符号表,并返回 */
/* 指向它的指针 */
/***********************************************************/
Cglobal::SymbTable * Canalyze::NewTable(void)
{
/* 内存中动态申请分配单元,返回指向该单元的符号表类型指针t */
SymbTable * table = (SymbTable *) malloc(sizeof(SymbTable));
/* 符号表类型指针table为NULL,未能成功分配内存单元 *
* 将出错信息及行号lineno写入列表文件listing */
if (table==NULL)
{
fprintf(listing,"Out of memory error !");
Error = TRUE;
}
table->next = NULL;
table->attrIR.kind = typeKind;
table->attrIR.idtype = NULL;
table->next = NULL;
table->attrIR.More.VarAttr.isParam = false;
/* 符号表类型指针table不是NULL,内存单元已经成功分配 */
return table;
}
/**********************************************************/
/*函数名 CreatTable */
/*功 能 创建空符号表 */
/*说 明 当进入一个新的局部化单位时,调用本子程序。功能是:*/
/* 建立一个空符号表table,层数加1,偏移初始化为0。 */
/**********************************************************/
void Canalyze::CreatTable(void)
{
Level = Level +1; /*层数加一*/
scope[Level] = NULL; /*申请了新的一层scope栈的空间*/
Off = INITOFF; /*偏移初始化*/
}
//void printTable();
/***********************************************************/
/* 函数名 DestroyTable */
/* 功 能 撤销当前符号表 */
/* 说 明 退出一个局部化区时,调用本子程序。功能是层数减1,*/
/* 并撤销当前符号表 */
/***********************************************************/
void Canalyze::DestroyTable()
{
/*如果语义分析跟踪标志为TURE,则将语法分析产生的符号表显示出来*/
/*if ((TraceTable)&&(Error==FALSE))
{
printTable();
getchar();
}*/
Level = Level - 1;
}
/***********************************************************/
/* 函数名 Enter */
/* 功 能 登记标识符和属性 */
/* 说 明 Enter的输入是一个标识符id和一个属性attrib以及 */
/* 符号表指针entry,而完成的任务是把给定id和属性 */
/* Atrrib登记到符号表中,并返回登记项的地址。在登 */
/* 记时应检查在本层中是否有重复声明错误,为此声明 */
/* Enter返回类型为bool,如果已有id项则该变量返回1 */
/* 值,否则返回0。 */
/***********************************************************/
int Canalyze::Enter(char * id, AttributeIR * attribP, SymbTable ** entry)
{
int present = FALSE;
int result = 1;
SymbTable * curentry = scope[Level];
SymbTable * prentry = scope[Level];
if(scope[Level]==NULL)
{
curentry = NewTable();
scope[Level] = curentry;
}
else
{
while (curentry != NULL)
{
prentry = curentry;
result = strcmp(id,curentry->idName);
if(result == 0)
{
fprintf(listing,"repetition declaration error !");
Error = TRUE;
present = TRUE;
}
else
curentry = (prentry->next);
} /*在该层符号表内检查是否有重复定义错误*/
if(present==FALSE)
{
curentry = NewTable();
prentry->next = curentry;
}
}
/*将标识符名和属性登记到表中*/
strcpy(curentry->idName,id);
curentry->attrIR.idtype = attribP->idtype;
curentry->attrIR.kind = attribP->kind;
switch( attribP->kind)
{
case typeKind : break;
case varKind :
curentry->attrIR.More.VarAttr.level =attribP->More.VarAttr.level;
curentry->attrIR.More.VarAttr.off=attribP->More.VarAttr.off;
curentry->attrIR.More.VarAttr.access=attribP->More.VarAttr.access;
break;
case procKind :
curentry->attrIR.More.ProcAttr.level=attribP->More.ProcAttr.level;
curentry->attrIR.More.ProcAttr.param=attribP->More.ProcAttr.param;
break;
default :break;
}
(* entry) = curentry;
return present;
}
/***********************************************************/
/* 函数名 FindEntry */
/* 功 能 寻找表项地址 */
/* 说 明 对给定的标识符id (id为字符串类型) 求出其表项地址,*/
/* 并在entry的实参单元中返回表项地址。如果符号表里没*/
/* 有所找的id项,则返回present为0,则函数中的参数entry*/
/* 赋值为指向该表项地址的指针;否则,present赋值为1。 */
/***********************************************************/
int Canalyze::FindEntry(char * id , SymbTable ** entry)
{
int present = FALSE; /*返回值*/
int result = 1; /*标识符名字比较结果*/
int lev = Level; /*临时记录层数的变量*/
SymbTable * findentry = scope[lev];
while((lev!=-1)&&(present!=TRUE))
{
while ((findentry!=NULL)&&(present!=TRUE))
{
result = strcmp(id,findentry->idName);
if ( result==0 )
present = TRUE;
/*如果标识符名字相同,则返回TRUE*/
else
findentry = findentry->next;
/*如果没找到,则继续链表中的查找*/
}
if(present!=TRUE)
{
lev = lev-1;
findentry = scope[lev];
}
}/*如果在本层中没有查到,则转到上一个局部化区域中继续查找*/
if (present!=TRUE)
{
(* entry) = NULL;
}
else
(* entry) = findentry;
return present;
}
/***********************************************************/
/* 函数名 FindAtrr */
/* 功 能 属性查询 */
/* 说 明 对给定表项地址,求出其属性值,并将其返回给Atrrib */
/* 的实参单元中。 */
/***********************************************************/
Cglobal::AttributeIR Canalyze::FindAttr(SymbTable * entry)
{
AttributeIR attrIr = entry->attrIR;
return attrIr;
}
/***********************************************************/
/* 函数名 Compat */
/* 功 能 判断类型是否相容 */
/* 说 明 由于TINY语言中只有整数类型、字符类型、数组类型和 */
/* 记录类型,故类型相容等于类型等价,只需判断每个结 */
/* 构类型的内部表示产生的指针值是否相同即可。 */
/***********************************************************/
int Canalyze::Compat(TypeIR * tp1,TypeIR * tp2)
{
int present;
if (tp1!=tp2)
present = FALSE; /*类型不等*/
else
present = TRUE; /*类型等价*/
return present;
}
/***********************************************************/
/* 函数名 NewTy */
/* 功 能 创建当前空类型内部表示 */
/* 说 明 参数为类型,函数返回该类型的内部表示的地址 */
/***********************************************************/
Cglobal::TypeIR * Canalyze::NewTy(TypeKind kind)
{
/* 内存中动态申请分配单元,
返回指向该单元的类型内部表示类型指针t */
TypeIR * table = (TypeIR *) malloc(sizeof(TypeIR));
/* 类型内部表示类型指针table为NULL,
未能成功分配内存单元将显示提示错误信息*/
if (table==NULL)
{
fprintf(listing,"Out of memory error !");
Error = TRUE;
}
/* 类型内部表示类型指针table不是NULL,内存单元已经成功分配 */
else
switch(kind)
{
case intTy:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -