?? symbtable.cpp
字號:
/****************************************************/
/* 文件 symbTable.cpp */
/* 說明 類PASCAL語言編譯器符號表處理程序 */
/* 主題 編譯器結(jié)構(gòu):原理和實例 */
/****************************************************/
/* 頭文件globals.h定義了全局類型與變量 */
#include "globals.h"
#include "stdio.h"
#include "string.h"
#include "util.h"
static void printTy(TypeIR * ty);
static void printVar(SymbTable * entry);
static void printProc(SymbTable * entry);
//static void printTab(int tabnum);
/**********************************************************/
/**************** 符號表相關(guān)操作 **********************/
/**********************************************************/
/********************************************************/
/* 函數(shù)名 PrintFieldTable */
/* 功 能 打印紀(jì)錄類型的域表 */
/* 說 明 */
/********************************************************/
void PrintFieldChain(fieldChain *currentP)
{
fprintf(listing,"\n--------------Field chain--------------------\n");
fieldChain *t=currentP;
while (t!=NULL)
{ /*輸出標(biāo)識符名字*/
fprintf(listing ,"%s: ",t->id );
/*輸出標(biāo)識符的類型信息*/
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;
}
}
/********************************************************/
/* 函數(shù)名 PrintOneLayer */
/* 功 能 打印符號表的一層 */
/* 說 明 有符號表打印函數(shù)PrintSymbTable調(diào)用 */
/********************************************************/
void PrintOneLayer(int level)
{
SymbTable *t= scope[level];
fprintf(listing,"\n-------SymbTable in level %d ---------\n",level);
while (t!=NULL)
{ /*輸出標(biāo)識符名字*/
fprintf(listing ,"%s: ",t->idName);
AttributeIR *Attrib = &(t->attrIR );
/*輸出標(biāo)識符的類型信息,過程標(biāo)識符除外*/
if (Attrib->idtype!=NULL) /*過程標(biāo)識符*/
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;
}
/*輸出標(biāo)識符的類別,并根據(jù)不同類型輸出不同其它屬性*/
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;
}
}
/********************************************************/
/* 函數(shù)名 PrintSymbTable */
/* 功 能 打印生成的符號表 */
/* 說 明 */
/********************************************************/
void PrintSymbTable( )
{ /*層數(shù)從0開始*/
int level=0;
while (scope[level]!=NULL)
{ PrintOneLayer(level);
level++;
}
}
/***********************************************************/
/* 函數(shù)名 NewTable */
/* 功 能 創(chuàng)建當(dāng)前空符號表 */
/* 說 明 遇到新的無聲明的標(biāo)識符時創(chuàng)建新的空符號表,并返回 */
/* 指向它的指針 */
/***********************************************************/
SymbTable * NewTable(void)
{
/* 內(nèi)存中動態(tài)申請分配單元,返回指向該單元的符號表類型指針t */
SymbTable * table = (SymbTable *) malloc(sizeof(SymbTable));
/* 符號表類型指針table為NULL,未能成功分配內(nèi)存單元 *
* 將出錯信息及行號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,內(nèi)存單元已經(jīng)成功分配 */
return table;
}
/**********************************************************/
/*函數(shù)名 CreatTable */
/*功 能 創(chuàng)建空符號表 */
/*說 明 當(dāng)進入一個新的局部化單位時,調(diào)用本子程序。功能是:*/
/* 建立一個空符號表table,層數(shù)加1,偏移初始化為0。 */
/**********************************************************/
void CreatTable(void)
{
Level = Level +1; /*層數(shù)加一*/
scope[Level] = NULL; /*申請了新的一層scope棧的空間*/
Off = INITOFF; /*偏移初始化*/
}
//void printTable();
/***********************************************************/
/* 函數(shù)名 DestroyTable */
/* 功 能 撤銷當(dāng)前符號表 */
/* 說 明 退出一個局部化區(qū)時,調(diào)用本子程序。功能是層數(shù)減1,*/
/* 并撤銷當(dāng)前符號表 */
/***********************************************************/
void DestroyTable()
{
/*如果語義分析跟蹤標(biāo)志為TURE,則將語法分析產(chǎn)生的符號表顯示出來*/
/*if ((TraceTable)&&(Error==FALSE))
{
printTable();
getchar();
}*/
Level = Level - 1;
}
/***********************************************************/
/* 函數(shù)名 Enter */
/* 功 能 登記標(biāo)識符和屬性 */
/* 說 明 Enter的輸入是一個標(biāo)識符id和一個屬性attrib以及 */
/* 符號表指針entry,而完成的任務(wù)是把給定id和屬性 */
/* Atrrib登記到符號表中,并返回登記項的地址。在登 */
/* 記時應(yīng)檢查在本層中是否有重復(fù)聲明錯誤,為此聲明 */
/* Enter返回類型為bool,如果已有id項則該變量返回1 */
/* 值,否則返回0。 */
/***********************************************************/
int 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);
} /*在該層符號表內(nèi)檢查是否有重復(fù)定義錯誤*/
if(present==FALSE)
{
curentry = NewTable();
prentry->next = curentry;
}
}
/*將標(biāo)識符名和屬性登記到表中*/
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;
}
/***********************************************************/
/* 函數(shù)名 FindEntry */
/* 功 能 尋找表項地址 */
/* 說 明 對給定的標(biāo)識符id (id為字符串類型) 求出其表項地址,*/
/* 并在entry的實參單元中返回表項地址。如果符號表里沒*/
/* 有所找的id項,則返回present為0,則函數(shù)中的參數(shù)entry*/
/* 賦值為指向該表項地址的指針;否則,present賦值為1。 */
/***********************************************************/
int FindEntry(char * id , SymbTable ** entry)
{
int present = FALSE; /*返回值*/
int result = 1; /*標(biāo)識符名字比較結(jié)果*/
int lev = Level; /*臨時記錄層數(shù)的變量*/
SymbTable * findentry = scope[lev];
while((lev!=-1)&&(present!=TRUE))
{
while ((findentry!=NULL)&&(present!=TRUE))
{
result = strcmp(id,findentry->idName);
if ( result==0 )
present = TRUE;
/*如果標(biāo)識符名字相同,則返回TRUE*/
else
findentry = findentry->next;
/*如果沒找到,則繼續(xù)鏈表中的查找*/
}
if(present!=TRUE)
{
lev = lev-1;
findentry = scope[lev];
}
}/*如果在本層中沒有查到,則轉(zhuǎn)到上一個局部化區(qū)域中繼續(xù)查找*/
if (present!=TRUE)
{
(* entry) = NULL;
}
else
(* entry) = findentry;
return present;
}
/***********************************************************/
/* 函數(shù)名 FindAtrr */
/* 功 能 屬性查詢 */
/* 說 明 對給定表項地址,求出其屬性值,并將其返回給Atrrib */
/* 的實參單元中。 */
/***********************************************************/
AttributeIR FindAttr(SymbTable * entry)
{
AttributeIR attrIr = entry->attrIR;
return attrIr;
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -