亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? codegen.cpp

?? 編譯原理學習使用的代碼 內容有從詞法分析到中間代碼生成的代碼 并且含有注釋
?? CPP
?? 第 1 頁 / 共 2 頁
字號:
/****************************************************/
/* 文件 codegen.cpp				  					*/
/* 說明 類PASCAL語言編譯器代碼生成程序  			*/
/* 主題 編譯器結構:原理和實例						*/	
/****************************************************/

#include "globals.h"		/*定義全局類型和變量 */

#include "util.h"			/*定義了一些實用函數*/

#include "string.h"

#include "codegen.h"		/*定義了目標代碼生成文件的界面*/		

#include "code.h"           /*目標代碼生成用到的一些實用函數*/

/*標號地址表*/
LabelAddr  *labelAddrT = NULL;

/*********函數聲明***********/
void    codeGen(CodeFile  *midcode, char * destcode);

void	arithGen(CodeFile  *midcode);

void    operandGen(ArgRecord  *arg);

void	compaGen(CodeFile  *midcode);

void	aaddGen(CodeFile  *midcode);

void	readGen(CodeFile  *midcode);

void	writeGen(CodeFile  *midcode);

void	returnGen(CodeFile  *midcode);

void	assigGen(CodeFile  *midcode);

void	labelGen(CodeFile  *midcode);

void	jumpGen(CodeFile  *midcode , int i);

void	jump0Gen(CodeFile  *midcode);

void	valactGen(CodeFile  *midcode);

void	varactGen(CodeFile  *midcode);

void	callGen(CodeFile  *midcode);

void	pentryGen(CodeFile  *midcode);

void	endprocGen(CodeFile  *midcode);

void    FindAddr(ArgRecord  *arg );

void	FindSp(int varlevel);

void    mentryGen(CodeFile  *midcode,int savedLoc);

/************************************************/
/* 函數名 codeGen								*/ 
/* 功  能 目標代碼生成主函數					*/		
/* 說  明 該函數通過掃描中間代碼序列產生目標代碼*/
/*        文件第二個參數codefile為目標代碼文件名*/
/************************************************/
void codeGen(CodeFile  *midcode, char * destcode)
{ 
   /* 在內存中動態分配字串單元,返回單元指針s,	*
	* codefile為存儲目標代碼的代碼文件名		*/
   char * s = (char *)malloc(strlen(destcode)+7);

   /* 將給定字串拷貝到s */
   strcpy(s,"File: ");

   /* 將目標代碼文件名的字串拼接到s */
   strcat(s,destcode);
   fprintf(listing,"\n\n");

   getchar();

   /* 生成代碼文件說明注釋,寫入代碼文件 */
   emitComment("TINY Compilation to TM Code");
   emitComment(s);
 
   /* 生成標準先驅指令 */
   emitComment("Standard prelude:");
   
   /* 寫入單元設置指令,清空0地址單元中內容 */
   emitRM("ST",ac,0,ac,"clear location 0");
   
   /* 寫入注釋,先驅指令寫完 */
   emitComment("End of standard prelude.");
   
   /*為主程序入口留一個跳轉語句*/
   int  savedLoc = emitSkip(1);

   /*循環處理各條中間代碼,調用相應得函數產生相應得目標代碼*/
   while  (midcode!=NULL)
   {
	 switch(midcode->codeR.codekind)
	 {	/*運算處理,包括算術運算和關系運算*/
		case	ADD:
		case	SUB:
		case	MULT:
		case	DIV:	
		case	LTC:
		case	EQC:
					arithGen(midcode);		break;
		/*地址加運算*/
		case   AADD:
					aaddGen(midcode);		break;
		/*輸入語句*/
		case   READC:
					readGen(midcode);		break;
		/*輸出語句*/
		case   WRITEC:
					writeGen(midcode);		break;
		/*返回語句*/
		case   RETURNC:
					returnGen(midcode);		break;
		/*賦值語句*/
		case   ASSIG:
					assigGen(midcode);		break;
		/*標號聲明語句*/
		case   LABEL:
		case   WHILESTART:
		case   ENDWHILE:
					labelGen(midcode);		break;
		/*跳轉語句*/
		case   JUMP:
					jumpGen(midcode,1);		break;
		/*條件跳轉語句*/
		case   JUMP0:
					jump0Gen(midcode);		break;
		/*形實參結合語句:形參是值參*/
		case   VALACT:
					valactGen(midcode);		break;
		/*形實參結合語句:形參是變參*/
		case   VARACT:
					varactGen(midcode);		break;
		/*過程調用語句*/
		case   CALL:
					callGen(midcode);		break;
		/*過程入口聲明*/
		case   PENTRY:
					pentryGen(midcode);		break;
		/*過程出口聲明*/
		case   ENDPROC:
					endprocGen(midcode);	break;
		/*主程序入口處理*/
		case   MENTRY:
				    mentryGen(midcode,savedLoc); break;

		default :  fprintf(listing , " midcode  bug.\n");
	 }
   midcode = midcode->next;
   }

   /*處理完主程序,退出AR*/
   emitComment("<- end of main ");
   /* 寫入注釋,標志文件執行的結束 */
   emitComment("End of execution.");
   /* 寫入停止指令,結束程序執行 */
   emitRO("HALT",0,0,0,"");
}

/************************************************/
/* 函數名 	arithGen							*/ 
/* 功  能 	生成算術運算的目標代碼				*/		
/* 說  明										*/
/************************************************/
void	arithGen(CodeFile  *midcode)
{
   /* 如果代碼生成追蹤標志TraceCode為TRUE,寫入注釋,標注操作開始 */
  if (TraceCode) 	  emitComment("-> Op");

  /*生成左操作數的目標代碼,值存在ac中*/
  operandGen(midcode->codeR.arg1);

  /* 暫存左操作數 */
  emitRM("LDA",ac2,0,ac,"op: store  left ");  
  
  /*生成右操作數的目標代碼,值存在ac中*/
  operandGen(midcode->codeR.arg2);

  /* 取出左操作數ac1*/
  emitRM("LDA",ac1,0,ac2,"op: load left");

  /*根據操作符,生成運算的目標代碼,ac中為計算結果*/
  switch(midcode->codeR.codekind)
  {		/*相加*/
		case	ADD:    emitRO("ADD",ac,ac1,ac,"op +");	break;
		/*相減*/
		case	SUB:    emitRO("SUB",ac,ac1,ac,"op -");	break;
		/*相乘*/
		case	MULT:   emitRO("MUL",ac,ac1,ac,"op *");	break;
		/*相除*/
		case	DIV:    emitRO("DIV",ac,ac1,ac,"op /");  break;
		/*小于*/
		case	LTC:  
						/* 寫入減指令,將(左-右)操作數相減,結果送累加器ac */
					    emitRO("SUB",ac,ac1,ac,"op <") ;  

					    /* 寫入判斷跳轉指令,如果累加器ac的值小于0,	*
					  	 * 則代碼指令指示器跳過兩條指令				*/
					    emitRM("JLT",ac,2,pc,"br if true") ;

					    /* 寫入載入常量指令,將累加器ac賦值為0 */
					    emitRM("LDC",ac,0,0,"false case") ; 

					    /* 寫入數值載入指令,代碼指令指示器pc跳過下一條指令 */
					    emitRM("LDA",pc,1,pc,"unconditional jmp") ;

					    /* 寫入載入常量指令,將累加器ac賦值為1 */
					    emitRM("LDC",ac,1,0,"true case") ;
					    break;

		/*等于*/
		case	EQC:
						/* 寫入減法指令,將左,右操作數相減,結果送累加器ac */
						emitRO("SUB",ac,ac1,ac,"op ==") ;

						/* 寫入判斷跳轉指令,如果累加器ac等于0,	*
						 * 代碼指令指示器pc跳過兩條指令			*/
						emitRM("JEQ",ac,2,pc,"br if true");

						/* 寫入載入常量指令,將累加器ac賦值為0 */
						emitRM("LDC",ac,0,0,"false case") ;

						/* 寫入數值載入指令,代碼指令指示器pc跳過一條指令 */
						emitRM("LDA",pc,1,pc,"unconditional jmp") ;

						/* 寫入載入常量指令,將累加器ac賦值為1 */
						emitRM("LDC",ac,1,0,"true case") ;
						break;
		default :       break;
  }

  /*后面要用ac,故保存ac*/
  emitRM("LDA",ac2,0,ac,"op: store  result ");  

  /*計算目的操作數的地址,存在ac中*/
  FindAddr(midcode->codeR.arg3);

  /*取出暫存的計算結果,存入ac1*/
  emitRM("LDA",ac1,0,ac2,"op: load result");

  /*計算結果存入目的操作數*/
  emitRM("ST",ac1,0,ac, "");

  /* 如果代碼生成追蹤標志TraceCode為TRUE,寫入注釋信息,標注操作結束 */
  if (TraceCode)  emitComment("<- Op") ;
 
}

/************************************************/
/* 函數名 	operandGen							*/ 
/* 功  能 	生成操作數的目標代碼				*/		
/* 說  明	分操作數為常數或者變量兩種情況處理	*/
/*			注意不能用ac2						*/
/************************************************/
void  operandGen(ArgRecord  *arg)
{
	switch(arg->form)
	{ /*操作數為常數*/
	  case  ValueForm :	   
			/* 如果代碼生成追蹤標志TraceCode為TRUE,寫入注釋,常數部分開始 */
			if (TraceCode) emitComment("-> Const") ;

			/* 生成載入常量指令,載入常量到累加器ac */
			emitRM("LDC",ac,arg->Attr.value,0,"load const");
	  
			/* 如果代碼生成追蹤標志TraceCode為TRUE,寫入注釋,常數部分結束 */
			if (TraceCode)  emitComment("<- Const") ;
			break; 

      /*分量為標號*/
	  case  LabelForm:
		  /* 如果代碼生成追蹤標志TraceCode為TRUE,寫入注釋,標號部分開始 */
			if (TraceCode) emitComment("-> Label") ;

			/* 生成載入標號指令,載入標號值到累加器ac */
			emitRM("LDC",ac,arg->Attr.label,0,"load label");
	  
			/* 如果代碼生成追蹤標志TraceCode為TRUE,寫入注釋,標號部分結束 */
			if (TraceCode)  emitComment("<- Label") ;
			break; 

	  /*操作數為變量,有可能是臨時變量*/
	  case  AddrForm:
			 /* 如果代碼生成追蹤標志TraceCode為TRUE,寫入注釋,標注標識符開始 */
			if (TraceCode) emitComment("-> var") ;
	  
			FindAddr(arg);
			/*其中ac返回的是源變量或臨時變量的絕對偏移*/
	  
			if(arg->Attr.addr.access==indir)
			{   
				
				/*取內容作為地址,再取內容*/
				emitRM("LD",ac1,0,ac,"indir load id value");
				emitRM("LD",ac,0,ac1,"");
			}
			else
			{   /*存的是值*/
				/* 寫入數值載入指令,載入變量標識符的值*/
				emitRM("LD",ac,0,ac,"load id value");
			}

			/* 如果代碼生成追蹤標志TraceCode為TRUE,寫入注釋,標注標識符結束 */
	  		if (TraceCode)  emitComment("<- var") ;
			break;
	 
	  default:  break;
	}
}

/************************************************/
/* 函數名 	aaddGen								*/ 
/* 功  能 	生成地址加操作的目標代碼			*/		
/* 說  明										*/
/************************************************/
void	aaddGen(CodeFile  *midcode)
{	/* 如果代碼生成追蹤標志TraceCode為TRUE,寫入注釋,aadd語句開始 */
	if(TraceCode)  emitComment("->address  add");
  
	if(midcode->codeR.arg1->Attr.addr.access == dir)
	{   /*ac中的地址即為基地址*/
		/*計算變量的絕對偏移,ac中存為變量的絕對偏移*/
        FindAddr(midcode->codeR.arg1);
	}
	else
	{   /*ac中的地址存放的內容為基地址*/
		/*計算變量的絕對偏移,ac中存為變量的絕對偏移*/
        FindAddr(midcode->codeR.arg1);
		emitRM("LD",ac,0,ac,"");
	}
    /*基地址轉存到ac2*/
    emitRM("LDA",ac2,0,ac,"op: store  baseaddr ");  

	/*求地址相加運算的偏移量,存在ac中*/
	operandGen(midcode->codeR.arg2);

	/*地址相加,結果在ac中*/
	emitRO("ADD",ac2,ac2,ac,"op +");
    
    /*求目的變量的地址,存入ac*/
    FindAddr(midcode->codeR.arg3);

    /*地址相加結果寫入目的變量*/
    emitRM("ST",ac2,0, ac,"");

}

/************************************************/
/* 函數名 	readGen								*/ 
/* 功  能 	生成讀操作的目標代碼				*/		
/* 說  明	根據變量是直接變量還是間接變量進行	*/
/*			不同的處理							*/
/************************************************/
void	readGen(CodeFile  *midcode)
{
	/*生成讀指令,該指令完成讀入外部數值到累加器ac2的動作*/
	emitRO("IN",ac2,0,0,"read integer value");

	/*計算變量的絕對偏移,ac中存為變量的絕對偏移*/
	FindAddr(midcode->codeR.arg1);
    
	if(midcode->codeR.arg1->Attr.addr.access == dir)
	{	/*直接存*/
		/*最后生成存儲指令*/
		emitRM("ST",ac2,0,ac," var read : store value");
	}
	else
	{
		/*以ac內容作為地址找變量單元,再存*/
		emitRM("LD",ac1,0,ac,"");
		emitRM("ST",ac2,0,ac1," indir var read : store value");
	}
}

/************************************************/
/* 函數名 	writeGen							*/ 
/* 功  能 	生成寫操作的目標代碼				*/		
/* 說  明	調用函數得到值,并產生輸出代碼		*/
/************************************************/
void	writeGen(CodeFile  *midcode)
{
	/*調用函數,得到輸出的值,存在ac中*/
	operandGen(midcode->codeR.arg1);
	
	/*生成寫指令,該指令完成將累加器ac中的值輸出的動作*/
	emitRO("OUT",ac,0,0,"write ac");

}

/************************************************/
/* 函數名 	returnGen							*/ 
/* 功  能 	生成返回語句的目標代碼				*/		
/* 說  明	返回過程調用的下一條語句,注意return*/
/*			語句只在過程中出現					*/
/************************************************/
void	returnGen(CodeFile  *midcode)
{
	/*從過程里跳出,所做的工作與過程結束相同*/
	endprocGen(midcode);

}

/************************************************/
/* 函數名 	assigGen							*/ 
/* 功  能 										*/		
/* 說  明										*/
/************************************************/

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
中文字幕欧美国产| 亚洲午夜精品网| 丰满白嫩尤物一区二区| 亚洲精品网站在线观看| 91久久奴性调教| 亚洲成人av一区| 国产精品区一区二区三区| 久久精品这里都是精品| 欧美精品 国产精品| 午夜久久久久久电影| 制服丝袜一区二区三区| 美女视频黄免费的久久| 国产精品欧美综合在线| 欧美日本韩国一区二区三区视频 | 成人久久视频在线观看| 午夜精品久久久久久久久久久 | 91精品国产综合久久久久久久 | 91丨国产丨九色丨pron| 蜜桃精品视频在线观看| 国产精品久久久久久妇女6080| 亚洲免费成人av| 久久超碰97人人做人人爱| 久久精品国产亚洲高清剧情介绍 | 国产精品毛片久久久久久久| 在线观看视频一区二区| 麻豆精品一二三| 国产精品系列在线| 91麻豆精品91久久久久久清纯| 国产原创一区二区三区| 亚洲综合在线免费观看| 久久久久久电影| 宅男噜噜噜66一区二区66| 色婷婷久久一区二区三区麻豆| 美腿丝袜亚洲一区| 亚洲精品一卡二卡| 1024国产精品| 国产精品午夜春色av| 欧美白人最猛性xxxxx69交| 欧洲精品一区二区三区在线观看| 成人av在线看| 国产东北露脸精品视频| 韩国一区二区三区| 久99久精品视频免费观看| 亚洲成人动漫在线免费观看| 一区二区三区视频在线看| 久久精品一二三| 久久久亚洲精品石原莉奈| 欧美日韩国产首页| 欧美性三三影院| 7777精品伊人久久久大香线蕉| 欧美老女人在线| 欧美日本一区二区| 久久精品视频一区二区| 中文字幕不卡在线播放| 国产精品你懂的| 亚洲欧美另类在线| 亚洲丶国产丶欧美一区二区三区| 亚洲国产精品影院| 日韩国产欧美一区二区三区| 久久亚洲春色中文字幕久久久| 久久亚洲综合色一区二区三区| 国产91综合一区在线观看| 成年人国产精品| 亚洲国产成人精品视频| 久久色.com| 日韩亚洲电影在线| 国产91精品久久久久久久网曝门| 国产精品久久久一本精品| 欧美日韩国产精选| 国产综合色视频| 国产精品色在线观看| 欧美日韩一区中文字幕| 成人动漫一区二区三区| 亚洲一区二区三区三| 国产日韩精品久久久| 欧美精品亚洲二区| 久久国产精品区| 日韩成人一级大片| 亚洲国产电影在线观看| 91久久奴性调教| 91丨九色porny丨蝌蚪| 亚洲国产日日夜夜| 久久影院视频免费| 91福利资源站| 国产一区二区三区在线观看免费视频 | 日本欧美大码aⅴ在线播放| 欧美成人国产一区二区| 欧美精品少妇一区二区三区| 久久综合九色综合97婷婷女人 | 欧美片网站yy| 亚洲欧洲精品一区二区三区| 国产v综合v亚洲欧| 国产精品嫩草影院av蜜臀| 91网页版在线| 国产精品91一区二区| 91黄色免费看| 精品1区2区3区| 成人午夜视频在线| heyzo一本久久综合| 亚洲精品一线二线三线无人区| 国产精品久久久爽爽爽麻豆色哟哟| 久久先锋资源网| 亚洲欧洲三级电影| 欧美日韩成人激情| 麻豆91精品91久久久的内涵| 精品国产乱子伦一区| 日本乱人伦aⅴ精品| 99久久99久久精品国产片果冻| 久久网站热最新地址| 3751色影院一区二区三区| 欧美性淫爽ww久久久久无| 日本一区二区免费在线观看视频 | 懂色av中文字幕一区二区三区| 亚洲国产另类av| 成人午夜免费av| 激情五月播播久久久精品| 日本aⅴ精品一区二区三区| 亚洲一区二区黄色| 亚洲最大色网站| 欧美日韩一区三区| 国产欧美va欧美不卡在线| 91蜜桃传媒精品久久久一区二区| 亚洲欧美怡红院| 成人av资源下载| 国产suv精品一区二区三区 | 日韩视频免费直播| 亚洲线精品一区二区三区| 91国在线观看| 欧美日本国产一区| 久久夜色精品国产噜噜av| 亚洲人成网站精品片在线观看| 欧美成人三级电影在线| 久久精品人人做人人爽人人| 精品亚洲成a人在线观看| 精品视频一区二区不卡| 亚洲特级片在线| 精品国产一区二区亚洲人成毛片 | 91久久国产最好的精华液| 日韩电影在线一区二区| 日本一区中文字幕 | 亚洲人一二三区| 韩国精品主播一区二区在线观看| 国产成人av电影在线播放| 成人免费av资源| 91蝌蚪国产九色| 欧美一卡二卡在线| 中文字幕乱码久久午夜不卡| 中文字幕在线不卡| 日韩极品在线观看| 成人免费毛片app| 91国偷自产一区二区三区观看| 久久久久9999亚洲精品| 麻豆freexxxx性91精品| 欧美日韩精品高清| 久久精品欧美一区二区三区不卡| 成人sese在线| 亚洲小说欧美激情另类| 91麻豆精品久久久久蜜臀 | 蜜臀va亚洲va欧美va天堂| 亚洲精品国产高清久久伦理二区| 国产精品无码永久免费888| 久久综合色一综合色88| 色国产综合视频| 欧美国产精品专区| 久久99精品国产麻豆不卡| 一区2区3区在线看| 久久综合九色综合97婷婷女人 | 一区二区三区在线观看国产| 日韩成人午夜精品| av亚洲产国偷v产偷v自拍| 91麻豆精品国产无毒不卡在线观看| 中文字幕乱码久久午夜不卡| 美女视频黄 久久| 欧美视频一区二区三区在线观看| 国产视频一区二区在线| 亚洲免费三区一区二区| 欧美精品亚洲一区二区在线播放| 狠狠色狠狠色综合系列| 天堂一区二区在线| 亚洲成精国产精品女| 欧美一级理论性理论a| 欧美一区三区四区| www激情久久| 久久综合色天天久久综合图片| 亚洲视频1区2区| 精品亚洲porn| 日韩一区和二区| 日一区二区三区| 色噜噜狠狠成人中文综合| 国产精品二三区| 国产成人激情av| 亚洲精品一区二区三区精华液 | 精品国产区一区| 91高清视频免费看| 在线观看日产精品| 久久久久久久久久美女| 一区二区三区在线看| 激情文学综合网| 日韩视频永久免费| 日本不卡的三区四区五区|