⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 语义分析.txt

📁 这是编译原理的源代码
💻 TXT
📖 第 1 页 / 共 4 页
字号:
// 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 + -