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

📄 midcode.cpp

📁 snl语言是一个简单的具有嵌套过程定义的过程式语言
💻 CPP
📖 第 1 页 / 共 2 页
字号:

/****************************************************/
/* 文件 midcode.cpp									*/
/* 说明 TINY编译器中间代码生成实现					*/
/****************************************************/

#include "globals.h"	/* 该头文件定义全局类型和变量 */

#include "util.h"		/*该头文件定义了一些实用函数*/

#include "symbTable.h"

#include "midcode.h"	/* 该头文件声明了中间代码生成文件的界面函数*/


/*临时变量编号,全局变量,每个过程开始都对TempOffset进行
  初始化,注:所以,不同过程中,可能有编号相同的临时变量,但是
  由于他们互不相干,所以不会有问题;而且优化部分是对基本块进行优化,
  每个基本块最大是一个过程,也不会有问题*/
int  TempOffset ;

/*标号值,全局变量*/
int  Label = 0;

/*指向第一条中间代码*/
CodeFile  *firstCode = NULL ;

/*指向当前最后一条中间代码*/
CodeFile  *lastCode = NULL ;

/***********函数声明******************/

CodeFile  *GenMidCode(TreeNode *t);

void	   GenProcDec(TreeNode *t);

void	   GenBody(TreeNode  *t);

void	   GenStatement(TreeNode *t);

void       GenAssignS(TreeNode *t);

ArgRecord *GenVar(TreeNode *t);

ArgRecord *GenArray(ArgRecord *V1arg,TreeNode *t,int low ,int size); 

ArgRecord *GenField(ArgRecord *V1arg,TreeNode *t ,fieldChain *head );		  
 		  
ArgRecord *GenExpr(TreeNode *t);

void	   GenCallS(TreeNode *t );

void	   GenReadS (TreeNode *t );

void	   GenWriteS(TreeNode *t );

void	   GenIfS(TreeNode  *t );

void	   GenWhileS(TreeNode *t);


/********************************************************/
/* 函数名  GenMidCode 	  								*/
/* 功  能  中间代码生成主函数							*/
/* 说  明  若有过程声明,调用过程声明的代码声明函数;   */
/*         调用程序体的代码生成函数						*/
/********************************************************/
CodeFile * GenMidCode(TreeNode *t)
{  
  /*若有过程声明,调用相应函数,产生过程声明的中间代码*/
  TreeNode *t1=t->child[1];
  while (t1!=NULL)
  { if (t1->nodekind==ProcDecK)
       GenProcDec(t1);
    t1=t1->sibling; 
  }
  
  /*display表相对于sp的偏移*/

  ArgRecord *Noff = ARGValue(StoreNoff);

  /*生成主程序入口声明代码*/
  CodeFile  *code = GenCode(MENTRY,NULL,NULL,Noff);

  /*初始化临时变量的开始编号,为临时变量区的第一个地址*/
  TempOffset = StoreNoff + 1;

  /*调用语句序列的代码生成函数*/
  GenBody(t->child[2]);

  /*回填主程序的AR的大小到主程序入口中间代码*/
  int size = TempOffset;
  ArgRecord  *sizeArg = ARGValue(size);
  code->codeR.arg2= sizeArg;

  return (firstCode) ;
}

/****************************************************/
/* 函数名  GenProcDec								*/
/* 功  能  过程声明中间代码生成函数					*/
/* 说  明  生成过程入口中间代码,生成过程体的中间   */
/*		   代码,生成过程出口的中间代码				*/	
/****************************************************/
void GenProcDec(TreeNode *t)
{
  
  /*得到过程的入口标号*/
  int ProcEntry = NewLabel( );
  
  /*过程名在符号表中的地址*/
  SymbTable  *Entry = t->table[0];
  /*过程入口标号,回填入节点中*/
  Entry->attrIR.More.ProcAttr.codeEntry = ProcEntry;

  /*过程的display表的偏移量*/
  int noff = Entry->attrIR.More.ProcAttr.nOff;
 
  /*得到过程的层数及其ARG结构*/
  int procLevel = Entry->attrIR.More.ProcAttr.level;
  ArgRecord *levelArg = ARGValue(procLevel);

  
  /*若过程内部仍有过程声明,调用相应函数,产生过程声明的中间代码*/
  TreeNode *t1=t->child[1];
  while (t1!=NULL)
  { if (t1->nodekind==ProcDecK)
       GenProcDec(t1);
    t1=t1->sibling; 
  }

  /*产生过程入口中间代码*/ 
  ArgRecord  *arg1=ARGLabel(ProcEntry);
  CodeFile *code = GenCode(PENTRY,arg1,NULL,levelArg);
  
  /*初始化临时变量的开始编号,为过程临时变量区的第一个地址*/
  TempOffset =  noff + procLevel+1;

  /*调用语句序列的代码生成函数处理过程体*/
  GenBody(t->child[2]);

  /*得到过程的AR的大小,回填入过程入口中间代码*/
  int size = TempOffset;
  ArgRecord *sizeArg = ARGValue(size);
  code->codeR.arg2 = sizeArg;

  /*产生过程出口中间代码*/
  GenCode(ENDPROC,NULL,NULL,NULL);
}

/****************************************************/
/* 函数名  GenBody									*/
/* 功  能  语句序列中间代码生成函数					*/
/* 说  明  用于处理过程体或者程序体,				*/
/*		   循环处理各个语句							*/	
/****************************************************/
void GenBody(TreeNode  *t)
{  
   TreeNode *t1 = t;
	/*令指针指向第一条语句*/
	if (t1->nodekind==StmLK)
		t1=t1->child[0];

   while (t1!=NULL)
   { /*调用语句处理函数*/
	   GenStatement(t1);
      t1= t1->sibling;
   }
}


/****************************************************/
/* 函数名  GenStatement								*/
/* 功  能  语句处理函数	        					*/
/* 说  明  根据语句的具体类型,分别调用相应的		*/
/*		   语句处理函数								*/
/****************************************************/
void  GenStatement(TreeNode  *t) 
{  
	switch(t->kind.stmt)
	{ case  AssignK :   GenAssignS(t);  break;
	  case  CallK:      GenCallS(t);    break;
	  case  ReadK:      GenReadS(t);    break;
      case  WriteK:     GenWriteS(t);	break;
	  case  IfK :       GenIfS (t);	    break;
	  case  WhileK:  	GenWhileS(t);	break;	
	  case 	ReturnK:    /*直接生成中间代码*/  	
		                GenCode(RETURNC,NULL,NULL,NULL);
						break;
	  default : break;
    }
}

/****************************************************/
/* 函数名  GenAssignS								*/
/* 功  能  赋值语句处理函数        					*/
/* 说  明  处理左部变量,处理右部表达式,生成       */
/*         赋值语句中间代码 						*/
/****************************************************/
void  GenAssignS(TreeNode *t)
{   /*调用赋值左部变量的处理函数*/
	ArgRecord *Larg = GenVar(t->child[0]);
    /*调用赋值右部表达式的处理函数*/
	ArgRecord *Rarg = GenExpr(t->child[1]);
    /*生成赋值语句中间代码*/
    GenCode(ASSIG,Rarg,Larg,NULL);
}

/****************************************************/
/* 函数名  GenVar									*/
/* 功  能  变量处理	函数        					*/
/* 说  明										    */
/****************************************************/
ArgRecord *GenVar(TreeNode *t)
{ 
    int low ,size;
	fieldChain  *head = NULL ;

    /*生成变量名的ARG结构, Entry为标识符在符号表中的地址*/
 	SymbTable  *Entry = t->table[0];
	ArgRecord  *V1arg = ARGAddr(t->name[0],
		                        Entry->attrIR.More.VarAttr.level,
		                        Entry->attrIR.More.VarAttr.off,
								Entry->attrIR.More.VarAttr.access);
    
	/*返回的ARG结构*/
	ArgRecord * Varg = NULL;
    switch(t->attr.ExpAttr.varkind)
	{ /*标识符变量情形*/
	  case IdV: 	Varg = V1arg; break;
	  /*数组成员变量情形*/
	  case ArrayMembV:
		  /*构造数组下届和数组大小的ARG结构*/
	       low = Entry->attrIR.idtype->More.ArrayAttr.low;
	       size = Entry->attrIR.idtype->More.ArrayAttr.elemTy->size;
		   Varg = GenArray(V1arg, t , low, size);
		   break;
	  /*域变量情形*/    
	  case FieldMembV:
		 	head = Entry->attrIR.idtype->More.body;
			Varg = GenField(V1arg,t ,head);
			break;
	  default : break;
	}
  return (Varg);
}
/****************************************************/
/* 函数名  GenArray									*/
/* 功  能  数组成员变量处理函数    					*/
/* 说  明  由函数GenVar或函数GenField调用		    */
/****************************************************/
      	  
ArgRecord  *GenArray(ArgRecord *V1arg,TreeNode *t,int low ,int size)  		  
{   /*处理下标表达式*/
	ArgRecord *Earg= GenExpr(t->child[0]);

	ArgRecord  *lowArg = ARGValue(low);

⌨️ 快捷键说明

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