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

📄 gongg.java

📁 一个java编译器
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
                 midcode=midcode+"EQ";  
             else if (kind.equals("LTC"))
                 midcode=midcode+"LT";  
             else if (kind.equals("READC"))
                 midcode=midcode+"READ";  
             else if (kind.equals("WRITEC"))
                 midcode=midcode+"WRITE";  
             else if (kind.equals("RETURNC"))
                 midcode=midcode+"RETURN";  
             else if (kind.equals("ASSIG"))
                 midcode=midcode+"ASSIG";  
             else if (kind.equals("AADD"))
                 midcode=midcode+"AADD";  
             else if (kind.equals("LABEL"))
                 midcode=midcode+"LABEL";  
             else if (kind.equals("JUMP0"))
                 midcode=midcode+"JUMP0";  
             else if (kind.equals("JUMP"))
                 midcode=midcode+"JUMP";  
             else if (kind.equals("CALL"))
                 midcode=midcode+"CALL";  
             else if (kind.equals("VARACT"))
                 midcode=midcode+"VARACT";  
             else if (kind.equals("VALACT"))
                 midcode=midcode+"VALACT";  
             else if (kind.equals("PENTRY"))
                 midcode=midcode+"PENTRY";  
             else if (kind.equals("ENDPROC"))
                 midcode=midcode+"ENDPROC";  
             else if (kind.equals("MENTRY"))
                 midcode=midcode+"MENTRY";  
             else if (kind.equals("ENDWHILE"))
                 midcode=midcode+"ENDWHILE";  
             else if (kind.equals("WHILESTART"))
                 midcode=midcode+"WHILESTART";
}
/********************************************************/
/* 函数名  PrintCotent  				*/
/* 功  能  打印ARG结构的内容				*/
/* 说  明  由函数PrintOneCode调用			*/
/********************************************************/
void PrintContent(ArgRecord arg)
{
             if (arg.form.equals("LabelForm"))
                 midcode=midcode+String.valueOf(arg.midAttr.label);
             else if (arg.form.equals("ValueForm")) 
                 midcode=midcode+String.valueOf(arg.midAttr.value);
             else if (arg.form.equals("AddrForm")) 
	     {   
		 if (arg.midAttr.addr.dataLevel!=-1)
		     midcode=midcode+arg.midAttr.addr.name;
		 else  
		     midcode=midcode+"temp"+String.valueOf(arg.midAttr.addr.dataOff);
	     }
}
/********************************************************/
/* 函数名  PrintOneCode 				*/
/* 功  能  打印一条中间代码				*/
/* 说  明  由函数PrintMidCode调用			*/
/********************************************************/
void PrintOneCode(CodeFile code)
{ 
             PrintCodeName(code.codeR.codekind);
             midcode=midcode+"    ";
             if (code.codeR.arg1!=null)
	         PrintContent(code.codeR.arg1);
             else  
                 midcode=midcode+"    ";
             midcode=midcode+"    ";
             if (code.codeR.arg2!=null)
	         PrintContent(code.codeR.arg2);
             else  
                 midcode=midcode+"    ";
             midcode=midcode+"    ";
             if (code.codeR.arg3!=null)
	         PrintContent(code.codeR.arg3);
             else                   
                 midcode=midcode+"    ";  
}
/********************************************************/
/* 函数名  PrintMidCode 				*/
/* 功  能  打印中间代码序列				*/
/* 说  明						*/
/********************************************************/
void PrintMidCode(CodeFile firstCode)
{   
    int i = 0;
    CodeFile code = firstCode;
    midcode="\n";
    while (code!=null)
    { 
         midcode=midcode+String.valueOf(i)+":  ";
         PrintOneCode(code);
	 midcode=midcode+"\n";
	 code = code.next;
	 i++;
    }
}

/****************************************************/
/* 函数名  ECCsave				    */
/* 功  能  公共表达式优化主函数    		    */
/* 说  明  循环对各个基本块进行公共表达式优化	    */
/****************************************************/
/*注:考虑将blocknum用作局部变量,全局变量封装不好*/
CodeFile ECCsave()
{ 
    blocknum = DivBaseBlock();
    /*循环对每个基本块进行公共表达式优化*/
    for (int i=0 ;i<blocknum;i++)
    {  
        /*基本块入口处置值编码表,
	  可用表达式表,临时变量等价表为空*/
	valuNumT = null;
	usableExprT = null;
	tempEquaT = null;

	/*基本块的ECC节省*/
        SaveInBlock(i);
    }
    /*返回优化后的中间代码*/
    return firstCode;
}
/****************************************************/
/* 函数名  SaveInBlock				    */
/* 功  能  基本块优化函数	    	            */
/* 说  明					    */
/****************************************************/
void SaveInBlock(int i)
{   
    int op1,op2,op3;
	
    /*指向基本块第一条语句*/
    CodeFile currentCode = baseBlock[i];
    CodeFile formerCode = null;
    CodeFile laterCode = null;

    /* 循环处理基本块中的各条语句*/
    while ((currentCode!=baseBlock[i+1])&&(currentCode!=null))
    {
        CodeFile substiCode = new CodeFile();
	/*进行等价替换*/
	EquaSubsti(currentCode);

	if ((currentCode.codeR.codekind.equals("ADD"))||(currentCode.codeR.codekind.equals("SUB"))||(currentCode.codeR.codekind.equals("MULT"))||(currentCode.codeR.codekind.equals("DIV"))||(currentCode.codeR.codekind.equals("LTC"))||(currentCode.codeR.codekind.equals("EQC"))||(currentCode.codeR.codekind.equals("AADD")))
	{ 
	    /*调用函数Process处理分量1,返回分量1的编码*/
	    op1 = Process(currentCode,1);
	    /*调用函数Process处理分量2,返回分量2的编码*/
	    op2 = Process(currentCode,2);

	    /*查找可用表达式代码表*/
	    FindECC(currentCode.codeR.codekind,op1,op2,substiCode);
	    /*若找到,当前代码可节省*/
	    if (substiCode.codeR.arg3!=null)
	    { 
                /*向临时变量等价表中添加一项*/
		AppendTempEqua(currentCode.codeR.arg3,substiCode.codeR.arg3);
		/*删除当前代码*/
		formerCode = currentCode.former;
		laterCode = currentCode.next;
		if (formerCode!=null)
		    formerCode.next = laterCode;
		if (laterCode!=null)
		    laterCode.former = formerCode;
                if (formerCode!=null) 
		    currentCode = formerCode;
                else 
                    currentCode = laterCode;
	    }				 
	    else  /*没找到,代码不可节省*/
	    { 
	        /*为结果变量构造一个新的编码,填入值编码表*/
		Vnumber++;
		op3 = Vnumber;
		AppendValuNum(currentCode.codeR.arg3,op3);
		/*构造对应的映象码*/
		MirrorCode mirror = GenMirror(op1,op2,op3);
		/*当前代码写入可用表达式代码表*/
	        AppendUsExpr(currentCode,mirror);
	    }
        }
	else if (currentCode.codeR.codekind.equals("ASSIG"))
        {
	    /*Process函数处理赋值右部,返回编码*/
	    op1 = Process(currentCode,1);
				
	    /*若是间接临时变量,op1是地址码;否则,是值码*/
	    op2 = op1;
				
	    /*替换编码表中赋值左部的值编码*/
	    SubstiVcode(currentCode.codeR.arg2,op2);

	    /*删除可用表达式代码表中用到赋值左部值编码的项*/
	    DelUsExpr(currentCode.codeR.arg2);
	}
	/*处理下一条代码*/
	currentCode = currentCode.next;
    }
}
/****************************************************/
/* 函数名  EquaSubsti				    */
/* 功  能  利用临时变量等价表对当前代码进行等价替换 */
/* 说  明  					    */
/****************************************************/
void EquaSubsti(CodeFile code)
{	
    TempEqua Entry = new TempEqua();
    if (code.codeR.arg1!=null)
	/*若操作数1是临时变量,且存在于临时变量等价表中,则替换*/
	if (code.codeR.arg1.form.equals("AddrForm"))
	    if(code.codeR.arg1.midAttr.addr.dataLevel == -1)
	    {	
                FindTempEqua(code.codeR.arg1,Entry);
		if (Entry.arg2!=null)
		    code.codeR.arg1 = Entry.arg2;
	    }
    if (code.codeR.arg2!=null)
	/*若操作数2是临时变量,且存在于临时变量等价表中,则替换*/
	if (code.codeR.arg2.form.equals("AddrForm"))
	    if (code.codeR.arg2.midAttr.addr.dataLevel == -1)
	    {	
                FindTempEqua(code.codeR.arg2,Entry);
		if (Entry.arg2!=null)
		    code.codeR.arg2 = Entry.arg2;
	    }
}
/****************************************************/
/* 函数名  Process				    */
/* 功  能  处理操作分量,并返回对应的编码	    */
/* 说  明  若首次出现,则分配新编码,填入编码表中, */
/*	   返回值取这个新的编码;否则,根据是否间接 */
/*	   变量,返回相应的值编码或地址码	    */	
/****************************************************/
int Process(CodeFile code,int i)
{
    ArgRecord arg;
    ValuNum Entry = new ValuNum();
    String codekind = code.codeR.codekind;
    int opC;
    if (i==1)
	arg = code.codeR.arg1;
    else    
        arg = code.codeR.arg2;
    /*若操作数首次出现,则填入编码表*/
    SearchValuNum(arg,Entry);
    if (Entry.access==null)
    { 
        Vnumber++;
	opC = Vnumber;  /*op1记录操作数1的值编码*/
	AppendValuNum(arg,opC);
    }
    else 
    {  
	/*间接临时变量*/
        if (Entry.access.equals("indir"))
	    /*用间接临时变量的地址码*/
	    if((codekind.equals("AADD"))||(codekind.equals("ASSIG")))
		/*取地址码*/
		opC= Entry.codeInfo.twoCode.addrcode;
	    else   /*否则,取值码*/
		opC = Entry.codeInfo.twoCode.valuecode;
	/*非间接临时变量*/
	else    
            opC = Entry.codeInfo.valueCode;
    }
    return opC;
}
/****************************************************/
/* 函数名  FindTempEqua				    */
/* 功  能  查找临时变量等价表			    */
/* 说  明  					    */
/****************************************************/
void FindTempEqua(ArgRecord arg,TempEqua Entry)
{	 
    TempEqua tItem = tempEquaT;
    while (tItem!=null)
    { /*注:因为是临时变量,故这里可以直接使用引用比较
	而一般变量则不行,因为同一个变量可能会产生
	多个内容相同的ARG结构,根据中间代码生成时的
	处理手段*/
	if (tItem.arg1 == arg)
	    break;
	tItem = tItem.next;
    }
    if (tItem!=null)
    {
        Entry.arg1 = tItem.arg1;
        Entry.arg2 = tItem.arg2;
        Entry.next = tItem.next;
    }    
}
/****************************************************/
/* 函数名  SearchValuNum			    */
/* 功  能  查找编码表				    */
/* 说  明  若存在于编码表中返回入口地址;否则返回空 */
/****************************************************/
void SearchValuNum(ArgRecord arg,ValuNum Entry)
{   
    boolean equal = false;
    /*指向编码表*/
    ValuNum vItem = valuNumT;
    while (vItem != null)
    {   /*比较是否有相同的变量*/  
	equal = IsEqual(vItem.arg,arg);
        if (equal)
	    break;
        vItem = vItem.next;
    }
    if (vItem!=null)
    {
        Entry.arg = vItem.arg;
        Entry.access = vItem.access;
        Entry.codeInfo = vItem.codeInfo;
        Entry.next = vItem.next;
    }
}
/****************************************************/
/* 函数名  IsEqual				    */
/* 功  能  判断两个ARG结构是否相同		    */
/* 说  明  这里运算分量没有标号,故只考虑了常量类   */
/*	   和地址类ARG结构			    */
/****************************************************/
boolean IsEqual(ArgRecord arg1,ArgRecord arg2)
{
    boolean equal = false;
    /*注:应比较ARG结构内容,不能比较引用,因为一个相同的变量
      可能会产生多个相同的ARG结构,由不同的引用,这是
      由中间代码生成时的处理策略决定的*/
    if (arg1.form == arg2.form)
    {
        if (arg1.form.equals("ValueForm"))
	{/*常数类:值相等则等价*/
	    if (arg1.midAttr.value == arg2.midAttr.value)
	        equal = true;
	}
	 /*地址类:层数,偏移,访问方式都相等时等价*/
	else if (arg1.form.equals("AddrForm"))
        { 
	    if ((arg1.midAttr.addr.dataLevel == arg2.midAttr.addr.dataLevel)
	    &&(arg1.midAttr.addr.dataOff == arg2.midAttr.addr.dataOff)
	    &&(arg1.midAttr.addr.access == arg2.midAttr.addr.access))
		equal = true;
	}
    }
    return equal;
}				
/****************************************************/
/* 函数名  AppendValuNum			    */
/* 功  能  当前变量及值写入值编码表中		    */
/* 说  明  申请一个新节点,根据变量是否为间接临时变 */
/*	   填写不同的内容,并联入表中		    */
/****************************************************/
void AppendValuNum(ArgRecord arg,int Vcode)
{   
    /*最后一个节点引用*/
    ValuNum last;
    /*申请一个新的值编码表的节点,并填写内容*/
    ValuNum newItem = new ValuNum();
    newItem.arg = arg;
    /*若是间接临时变量*/
    if ((arg.form.equals("AddrForm"))&&(arg.midAttr.addr.dataLevel == -1)&&(arg.midAttr.addr.access.equals("indir")))
    { 
	newItem.access = "indir";
        newItem.codeInfo.twoCode = new TwoCode();
        newItem.codeInfo.twoCode.valuecode = Vcode;
	newItem.codeInfo.twoCode.addrcode = Vcode;
    }
    else 
    {
        /*其余情况为:非间接临时变量*/		
	newItem.access = "dir";
	newItem.codeInfo.valueCode = Vcode;
    }	
    /*节点联入值编码表中*/
    if (valuNumT == null)
	valuNumT = newItem;
    else 
    {  
        last = valuNumT;
	while (last.next!=null)
	    last = last.next;
	last.next = newItem;
    }
}
/****************************************************/
/* 函数名  AppendTempEqua			    */
/* 功  能  将两个等价的临时变量写入临时变量等价表中 */
/* 说  明  表示第一项可以被第二项替换		    */
/****************************************************/
void AppendTempEqua(ArgRecord arg1,ArgRecord arg2)
{
    /*最后一个节点指针*/
    TempEqua last;
    /*申请一个新的临时变量等价表的节点,并填写内容*/
    TempEqua newItem = new TempEqua();
    newItem.arg1 = arg1;
    newItem.arg2 = arg2;

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

⌨️ 快捷键说明

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