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

📄 eccsaving.cpp

📁 snl语言是一个简单的具有嵌套过程定义的过程式语言
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/****************************************************/
/* 函数名  FindTempEqua								*/
/* 功  能  查找临时变量等价表						*/
/* 说  明  										    */
/****************************************************/
TempEqua  *FindTempEqua(ArgRecord *arg)
{	 
	TempEqua  *Item = tempEquaT ;
	while (Item!=NULL)
	{ /*注:因为是临时变量,故这里可以直接使用指针比较
		    而一般变量则不行,因为同一个变量可能会产生
		    多个内容相同的ARG结构,根据中间代码生成时的
		    处理手段*/
	  if (Item->arg1 == arg)
	     break;
	  Item = Item->next;
	}
   return (Item);
}


	
/****************************************************/
/* 函数名  SearchValuNum							*/
/* 功  能  查找编码表								*/
/* 说  明  若存在于编码表中返回入口地址;否则返回空 */
/****************************************************/
ValuNum *SearchValuNum(ArgRecord  *arg)
{   
	bool  equal = false;
    /*指向编码表*/
	ValuNum  *Item = valuNumT;
	while (Item != NULL)
	{   /*比较是否有相同的变量*/  
		equal = IsEqual(Item->arg,arg);
        if  (equal)
			  break;

		Item = Item->next;
	}
    return(Item);
}


/****************************************************/
/* 函数名  IsEqual									*/
/* 功  能  判断两个ARG结构是否相同					*/
/* 说  明  这里运算分量没有标号,故只考虑了常量类	*/
/*		   和地址类ARG结构							*/
/****************************************************/
bool  IsEqual(ArgRecord *arg1,ArgRecord  *arg2)
{
  bool  equal = false ;
  /*注:应比较ARG结构内容,不能比较指针,因为一个相同的变量
        可能会产生多个相同的ARG结构,由不同的指针指向,这是
		由中间代码生成时的处理策略决定的*/
  if (arg1->form == arg2->form)
	switch(arg1->form)
	{/*常数类:值相等则等价*/
     case  ValueForm : 
	     if (arg1->Attr.value == arg2->Attr.value)
				equal = true ;
		 break;
	 /*地址类:层数,偏移,访问方式都相等时等价*/
	 case  AddrForm:
		 if ((arg1->Attr.addr.dataLevel == arg2->Attr.addr.dataLevel)
	        &&(arg1->Attr.addr.dataOff == arg2->Attr.addr.dataOff)
			&&(arg1->Attr.addr.access == arg2->Attr.addr.access))
			   equal  = true ;
		 break;
	 default :break;
	}
	return (equal);
}
				
/****************************************************/
/* 函数名  AppendValuNum							*/
/* 功  能  当前变量及值写入值编码表中				*/
/* 说  明  申请一个新节点,根据变量是否为间接临时变 */
/*		   填写不同的内容,并联入表中				*/
/****************************************************/
void  AppendValuNum(ArgRecord *arg , int  Vcode)
{   
    /*最后一个节点指针*/
	ValuNum  *last ;
	/*申请一个新的值编码表的节点,并填写内容*/
	ValuNum  *newItem = (ValuNum  *)malloc(sizeof(ValuNum));
	newItem->arg = arg ;
	newItem->next = NULL;
	/*若是间接临时变量*/
    if (arg->form == AddrForm )
		if (arg->Attr.addr.dataLevel == -1)
			if (arg->Attr.addr.access == indir )
			{ 
				newItem->access = indir ;
				newItem->codeInfo.twoCode.valuecode = Vcode;
				newItem->codeInfo.twoCode.addrcode = Vcode;

				goto  L1;
			}
   /*其余情况为:非间接临时变量*/
		
		  newItem->access = dir;
	      newItem->codeInfo.valueCode = Vcode;
	
L1:  /*节点联入值编码表中*/
    if (valuNumT == NULL)
		valuNumT = newItem;
	else 
	{  last = valuNumT ;
		while (last->next!=NULL)
			last = last->next;
	    last->next = newItem;
	}
}

/****************************************************/
/* 函数名  FindECC									*/
/* 功  能  判断可用表达式表中是否有可用的表达式代码 */
/* 说  明  若有,返回用于替换的中间代码指针			*/
/*		   否则,返回为空							*/
/****************************************************/
CodeFile *FindECC(CodeKind  codekind,int  op1Code, int  op2Code)
{   
	CodeFile  * substiCode =NULL;
	UsableExpr  *currentItem = usableExprT;

	while ((currentItem != NULL)&&(substiCode==NULL))
	{   /*语句类别相同*/
		if (currentItem->code->codeR.codekind == codekind )
			/*对应分量编码都相同,可替换*/
			if ((currentItem->mirrorC->op1== op1Code)&&(currentItem->mirrorC->op2 == op2Code))
					substiCode = currentItem->code;
			else
				/*可交换运算符,分量编码交叉相同,也可替换*/
				if ((codekind ==ADD)||(codekind == MULT))
		 	 		if ((currentItem->mirrorC->op1== op2Code)&&(currentItem->mirrorC->op1 == op2Code))
								substiCode = currentItem->code;

		currentItem = currentItem->next;
	}
	return (substiCode);
}
	

/****************************************************/
/* 函数名  AppendTempEqua							*/
/* 功  能  将两个等价的临时变量写入临时变量等价表中	*/
/* 说  明  表示第一项可以被第二项替换				*/
/****************************************************/
void  AppendTempEqua(ArgRecord  *arg1,ArgRecord  *arg2)
{
   /*最后一个节点指针*/
	TempEqua  *last ;
	/*申请一个新的临时变量等价表的节点,并填写内容*/
	TempEqua  *newItem = (TempEqua  *)malloc(sizeof(TempEqua));
	newItem->arg1 = arg1;
	newItem->arg2 = arg2;
	newItem->next = NULL;

   /*节点联入临时变量等价表中*/
    if (tempEquaT == NULL)
		tempEquaT = newItem;
	else 
	{  last = tempEquaT ;
		while (last->next!=NULL)
			last = last->next;
	    last->next = newItem;
	}
}

/****************************************************/
/* 函数名  GenMirror								*/
/* 功  能  构造映象码								*/
/* 说  明											*/
/****************************************************/
MirrorCode * GenMirror(int op1,int op2,int result)
{
	MirrorCode  *mirror = (MirrorCode *) malloc (sizeof(MirrorCode));
	mirror->op1 = op1;
	mirror->op2 = op2;
	mirror->result = result ;

	return (mirror);
}

/****************************************************/
/* 函数名  AppendUsExpr								*/
/* 功  能  将中间代码和相应的映象码写可用表达式表中	*/
/* 说  明											*/
/****************************************************/	
void  AppendUsExpr(CodeFile  *code,MirrorCode  *mirror)
{
	UsableExpr  *last ;
	UsableExpr  *newItem = (UsableExpr  *)malloc(sizeof(UsableExpr));
	newItem->code = code;
    newItem->mirrorC = mirror;
	newItem->next = NULL;

	if (usableExprT==NULL)
		usableExprT = newItem ;
	else 
	{ last = usableExprT ;
	  while (last->next!=NULL)
		  last = last->next ;
	  last->next = newItem;
	}
}

/****************************************************/
/* 函数名  SubstiVcode								*/
/* 功  能  将当前变量,及其值编码写入编码表			*/
/* 说  明  若变量首次出现,则添加一项;否则,将表中	*/
/*		   此变量的值编码替换为新的值编码			*/
/****************************************************/	
void  SubstiVcode(ArgRecord  *arg,int Vcode)
{
	ValuNum  *Entry = SearchValuNum(arg );
	/*若操作数首次出现,则填入编码表*/
	if( Entry==NULL)
		  AppendValuNum(arg , Vcode);
	else 
	{ 
		/*间接临时变量*/
	   if (Entry->access == indir)
			Entry->codeInfo.twoCode.valuecode = Vcode;				
		/*非间接临时变量*/
	   else    Entry->codeInfo.valueCode = Vcode;
	}
		
}

/****************************************************/
/* 函数名  DelUsExpr								*/
/* 功  能  将可用表达式代码表中用到arg的值编码的项  */
/*		   删除										*/
/* 说  明											*/
/****************************************************/	
void DelUsExpr(ArgRecord  *arg)
{
	bool  same = false ;
	UsableExpr  *Item = usableExprT;
	UsableExpr  *former = Item ;  
    while (Item!=NULL)
	{   /*因为AADD用的是地址码,所以不考虑*/
		if (Item->code->codeR.codekind!=AADD)
		{ if (Item->code->codeR.arg1==arg)
				same = true;
		  else if (Item->code->codeR.arg2 == arg)
			       same = true;
			   else  if (Item->code->codeR.arg3 == arg)
							same = true;
		  if (same) 
		  { /*删除这个可用表达式项*/ 
			  if (Item == usableExprT)
			  {  usableExprT = Item->next;
			     free(Item);
				 former = Item = usableExprT;
			  }
			  else 
			  {  former->next = Item->next;
			     free(Item);
				 Item = former->next;
			  }
              /*跳到下一次循环开始处*/
		      continue;
		  }
		}
      /*指针后移,比较下一个节点*/
	  former = Item;
	  Item = Item->next;
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -