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

📄 midcode.cpp

📁 snl语言是一个简单的具有嵌套过程定义的过程式语言
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// midcode.cpp: implementation of the Cmidcode class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "face.h"
#include "midcode.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

Cmidcode::Cmidcode()
{


/*标号值,全局变量*/
Label = 0;
/*指向第一条中间代码*/
firstCode = NULL ;
/*指向当前最后一条中间代码*/
lastCode = NULL ;

/*主程序的noff偏移*/
mainOff = 0;

//TempOffset = 0;

}

Cmidcode::~Cmidcode()
{

}

/*******************实用函数的实现**************************/


/********************************************************/
/* 函数名  FindField	  								*/
/* 功  能  查找纪录的域名								*/
/* 说  明  返回值为是否找到标志,变量Entry返回此域名在  */
/*		   纪录的域表中的位置.							*/
/********************************************************/
bool  Cmidcode::FindField(char * Id , fieldChain  *head,fieldChain  **Entry )
{ 
	bool  present =false;
   /*记录当前节点*/
	fieldChain *currentItem = head;
   /*从表头开始查找这个标识符,直到找到或到达表尾*/
   while ((currentItem!=NULL)&&( present==false))
   { 
	  if  (strcmp(currentItem->id, Id )==0) 
	  { present= true;
	    if (Entry!=NULL)
	       (*Entry)=currentItem;
      }
      else  currentItem=currentItem->Next;
   }

  return(present);
}


/********************************************************/
/* 函数名  NewTemp		  								*/
/* 功  能  产生一个新的临时变量的ARG结构				*/
/* 说  明  临时变量的层数为-1,偏移为编号值,访问方式由 */
/*		   参数确定										*/
/********************************************************/
Cglobal::ArgRecord  *Cmidcode::NewTemp (AccessKind  access )
{  
   ArgRecord  *newTemp=(ArgRecord *)malloc(sizeof(ArgRecord)) ;
   /*填写临时变量的ARG内容*/
   
   newTemp->form = AddrForm ;
   newTemp->Attr.addr.dataLevel = -1 ;
   newTemp->Attr.addr.dataOff=TempOffset ;
   newTemp->Attr.addr.access= access;
   /*临时变量编号加1*/   
   TempOffset++;
      
   return (newTemp);
}

/********************************************************/
/* 函数名  NewLabel		  								*/
/* 功  能  产生一个新的标号值							*/
/* 说  明  通过全局变量Label加1,产生新的标号值			*/
/********************************************************/
int  Cmidcode::NewLabel()
{  Label++;  
   return (Label);
}

/********************************************************/
/* 函数名  ARGAddr		  								*/
/* 功  能  对于给定的变量产生相应的ARG结构				*/
/* 说  明  												*/
/********************************************************/

Cglobal::ArgRecord  *Cmidcode::ARGAddr(char  *id ,int level, int off, AccessKind access)
{   
	ArgRecord  *arg = (ArgRecord *)malloc(sizeof(ArgRecord));
	/*填写变量ARG结构的内容*/
    arg->form = AddrForm ;
	strcpy(arg->Attr.addr.name,id);
	arg->Attr.addr.dataLevel=level;
	arg->Attr.addr.dataOff=off;
    arg->Attr.addr.access=access;
		  
    return  (arg);
}
/********************************************************/
/* 函数名  ARGLabel		  								*/
/* 功  能  对于给定的标号产生相应的ARG结构				*/
/* 说  明  												*/
/********************************************************/
Cglobal::ArgRecord *Cmidcode::ARGLabel(int  label )
{  ArgRecord  *arg = (ArgRecord *) malloc (sizeof(ArgRecord));
   arg->form = LabelForm ;
   arg->Attr.label = label ;

   return (arg);
}

/********************************************************/
/* 函数名  ARGValue		  								*/
/* 功  能  对于给定的常数值产生相应的ARG结构			*/
/* 说  明  												*/
/********************************************************/
Cglobal::ArgRecord  *Cmidcode::ARGValue(int value)
{ ArgRecord  *arg = (ArgRecord *) malloc (sizeof(ArgRecord));
  arg->form = ValueForm ;
  arg->Attr.value = value ;

  return (arg);
}


/********************************************************/
/* 函数名  GenCode 		  								*/
/* 功  能  根据给定参数,构造一条中间代码				*/
/* 说  明												*/
/********************************************************/

Cglobal::CodeFile *Cmidcode::GenCode (CodeKind codekind , ArgRecord *Arg1 ,
									  ArgRecord *Arg2 ,ArgRecord *Arg3 )
{ 
    CodeFile  *newCode = (CodeFile  *) malloc (sizeof (CodeFile ));
    /*填写代码的内容*/	
	newCode->codeR.codekind = codekind ;
	newCode->codeR.arg1 = Arg1;  
	newCode->codeR.arg2 = Arg2;
	newCode->codeR.arg3 = Arg3;
	newCode->former = NULL;
	newCode->next = NULL;
    /*链入中间代码表中*/
	if  (firstCode==NULL)
		 firstCode = newCode ;
	else
	{	   lastCode->next=newCode;
		   newCode->former = lastCode;
	}
	lastCode = newCode ;

	return(newCode);
}
/********************************************************/
/* 函数名  PrintCodeName  								*/
/* 功  能  打印代码的类别								*/
/* 说  明  由函数PrintOneCode调用						*/
/********************************************************/
void  Cmidcode::PrintCodeName(CodeKind kind)
{
  switch(kind)
  {	case	ADD:		fprintf(listing ,"ADD");     break;
    case    SUB:		fprintf(listing ,"SUB");	 break;
	case	MULT:       fprintf(listing ,"MULT");    break;
	case	DIV:		fprintf(listing ,"DIV");     break;
	case	EQC:		fprintf(listing ,"EQ");      break;
	case	LTC:		fprintf(listing ,"LT");      break;
	case	READC:		fprintf(listing ,"READ");    break;
	case	WRITEC:		fprintf(listing ,"WRITE");	 break;
	case	RETURNC:	fprintf(listing ,"RETURN");  break;
	case	ASSIG:		fprintf(listing ,"ASSIG");   break;
	case    AADD:		fprintf(listing ,"AADD");    break;
	case    LABEL:		fprintf(listing ,"LABEL");   break;
	case    JUMP0:		fprintf(listing ,"JUMP0");   break;
	case    JUMP:		fprintf(listing ,"JUMP");    break;
	case    CALL:		fprintf(listing ,"CALL");    break;
	case    VARACT:		fprintf(listing ,"VARACT");  break;
	case    VALACT:		fprintf(listing ,"VALACT");  break;
	case    PENTRY:		fprintf(listing ,"PENTRY");  break;
	case    ENDPROC:	fprintf(listing ,"ENDPROC"); break;
	case    MENTRY:		fprintf(listing ,"MENTRY");  break;
	case    WHILESTART: fprintf(listing ,"WHILESTART");break;
	case    ENDWHILE:   fprintf(listing ,"ENDWHILE");  break;
	default:  break;
  }
}

/********************************************************/
/* 函数名  PrintCotent  								*/
/* 功  能  打印ARG结构的内容							*/
/* 说  明  由函数PrintOneCode调用						*/
/********************************************************/
void Cmidcode::PrintContent(ArgRecord  *arg)
{
	switch(arg->form)
	{case  LabelForm : fprintf(listing ,"%d",arg->Attr.label); break;
	 case  ValueForm : fprintf(listing ,"%d",arg->Attr.value); break;
	 case  AddrForm: 
		 //d:fprintf(listing ,"(");
		 if (arg->Attr.addr.dataLevel!=-1)
		      fprintf(listing ,arg->Attr.addr.name);
		 else 
		 { fprintf(listing ,"temp");
		        fprintf(listing ,"%d",arg->Attr.addr.dataOff);
		 }
		 /*
		 fprintf(listing ," , ");
		 fprintf(listing ,"%d",arg->Attr.addr.dataLevel);
		 fprintf(listing ," , ");
		 fprintf(listing ,"%d",arg->Attr.addr.dataOff);
		 fprintf(listing ," , ");
		 switch( arg->Attr.addr.access)
		 { case dir :  fprintf(listing ,"dir");   break;
		   case indir: fprintf(listing ,"indir"); break;
		   default  : break;
		  }
		 fprintf(listing ,")");
	     */
		 break;
	 default:  break;
	}
}

/********************************************************/
/* 函数名  PrintOneCode 								*/
/* 功  能  打印一条中间代码								*/
/* 说  明  由函数PrintMidCode调用						*/
/********************************************************/
void Cmidcode::PrintOneCode(CodeFile  *code)
{ 
    PrintCodeName(code->codeR.codekind);
	fprintf(listing ,"    ");
	if (code->codeR.arg1!=NULL)
		PrintContent(code->codeR.arg1);
	else  fprintf(listing, "  ");
	fprintf(listing ,"    ");
	if (code->codeR.arg2!=NULL)
		PrintContent(code->codeR.arg2);
	else  fprintf(listing ,"  ");
	fprintf(listing ,"    ");
	if (code->codeR.arg3!=NULL)
		PrintContent(code->codeR.arg3);
	else  fprintf(listing, "  ");
}

/********************************************************/
/* 函数名  PrintMidCode 								*/
/* 功  能  打印中间代码序列								*/
/* 说  明												*/
/********************************************************/
void  Cmidcode::PrintMidCode(CodeFile  *firstCode)
{   int i = 0;
	CodeFile  *code = firstCode ;
	while (code!=NULL)
	{ fprintf(listing ,"           ");
    	fprintf(listing ,"%d%s",  i, ":  ");
	  PrintOneCode(code);
	  fprintf(listing,"\n");
	  code = code ->next;
	  i++;
	}
}


/**************中间代码生成的函数实现************************/

/********************************************************/
/* 函数名  GenMidCode 	  								*/
/* 功  能  中间代码生成主函数							*/
/* 说  明  若有过程声明,调用过程声明的代码声明函数;   */
/*         调用程序体的代码生成函数						*/
/********************************************************/
Cglobal::CodeFile * Cmidcode::GenMidCode(TreeNode *t,int StoreNoff)
{  

/**********从构造函数拷贝,每次调用都要初始化**********/  
	/*标号值,全局变量*/
	Label = 0;
	/*指向第一条中间代码*/
	firstCode = NULL ;
	/*指向当前最后一条中间代码*/
	lastCode = NULL ;

	/*主程序的noff偏移*/
	mainOff = 0;

	//TempOffset = 0;
/**********************************************************/

  /*若有过程声明,调用相应函数,产生过程声明的中间代码*/
  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 Cmidcode::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);
  
  /*初始化临时变量的开始编号,为过程临时变量区的第一个地址*/

⌨️ 快捷键说明

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