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

📄 target.java

📁 这是编译原理的目标代码生成器java代码
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
{   
    /*生成else部分入口标号,及其ARG结构*/
    int elseL = NewLabel();
    ArgRecord ElseLarg=ARGLabel(elseL);

    /*生成if语句出口标号,及其ARG结构*/
    int outL = NewLabel();
    ArgRecord OutLarg = ARGLabel(outL);

    /*条件表达式的中间代码生成*/
    ArgRecord Earg = GenExpr(t.child[0]);

    /*若表达式为假,跳转至else入口标号*/
    GenCode("JUMP0",Earg,ElseLarg,null);
    
    /*then部分中间代码生成*/
    GenBody(t.child[1]);
    
    /*跳到if出口*/
    GenCode("JUMP",OutLarg,null,null);

    /*else部分入口标号声明*/
    GenCode("LABEL",ElseLarg,null,null);

    /*else部分中间代码生成*/
    GenBody(t.child[2]);

    /*if语句出口标号声明*/
    GenCode("LABEL",OutLarg,null,null);
}
/****************************************************/
/* 函数名  GenWhileS				    */
/* 功  能  循环语句处理函数        		    */
/* 说  明  将循环入口和出口用不同的中间代码标志,是 */
/*	   为了循环不变式外提的需要		    */
/****************************************************/
void GenWhileS(TreeNode t)
{   
    /*生成while语句入口标号,及其ARG结构*/
    int inL = NewLabel() ;
    ArgRecord InLarg = ARGLabel(inL);

    /*生成while语句出口标号,及其ARG结构*/
    int outL = NewLabel();
    ArgRecord OutLarg = ARGLabel(outL);

    /*while语句入口标号声明*/
    GenCode("WHILESTART",InLarg,null,null);
    
    /*条件表达式的中间代码生成*/
    ArgRecord Earg = GenExpr(t.child[0]);

    /*若表达式为假,跳转至while语句出口*/
    GenCode("JUMP0",Earg,OutLarg,null);
    
    /*循环体中间代码生成*/
    GenBody(t.child[1]);
    
    /*跳到while入口*/
    GenCode("JUMP",InLarg,null,null);

    /*while出口标号声明*/
    GenCode("ENDWHILE",OutLarg,null,null);
}
/********************************************************/
/* 函数名  NewTemp		  			*/
/* 功  能  产生一个新的临时变量的ARG结构		*/
/* 说  明  临时变量的层数为-1,偏移为编号值,访问方式由 */
/*	   参数确定					*/
/********************************************************/
ArgRecord NewTemp(String access)
{  
    ArgRecord newTemp=new ArgRecord();
    /*填写临时变量的ARG内容*/
   
    newTemp.form="AddrForm";
    newTemp.midAttr.addr=new Addr();
    newTemp.midAttr.addr.dataLevel=-1 ;
    newTemp.midAttr.addr.dataOff=TempOffset ;
    newTemp.midAttr.addr.access=access;
    /*临时变量编号加1*/   
    TempOffset++;
      
    return newTemp;
}
/********************************************************/
/* 函数名  NewLabel		  			*/
/* 功  能  产生一个新的标号值				*/
/* 说  明  通过全局变量Label加1,产生新的标号值		*/
/********************************************************/
int NewLabel()
{  
    Label++;  
    return Label;
}
/********************************************************/
/* 函数名  ARGAddr		  			*/
/* 功  能  对于给定的变量产生相应的ARG结构		*/
/* 说  明  						*/
/********************************************************/
ArgRecord ARGAddr(String id,int level,int off,String access)
{   
    ArgRecord arg = new ArgRecord();
    /*填写变量ARG结构的内容*/
    arg.form = "AddrForm";
    arg.midAttr.addr=new Addr();
    arg.midAttr.addr.name=id;
    arg.midAttr.addr.dataLevel=level;
    arg.midAttr.addr.dataOff=off;
    arg.midAttr.addr.access=access;
		  
    return arg;
}
/********************************************************/
/* 函数名  ARGLabel		  			*/
/* 功  能  对于给定的标号产生相应的ARG结构		*/
/* 说  明  						*/
/********************************************************/
ArgRecord ARGLabel(int label)
{  
    ArgRecord arg = new ArgRecord();
    arg.form = "LabelForm";
    arg.midAttr.label = label;

    return arg;
}
/********************************************************/
/* 函数名  ARGValue		  			*/
/* 功  能  对于给定的常数值产生相应的ARG结构	        */
/* 说  明  						*/
/********************************************************/
ArgRecord ARGValue(int value)
{ 
    ArgRecord arg = new ArgRecord();
    arg.form = "ValueForm";
    arg.midAttr.value = value;

    return arg;
}
/********************************************************/
/* 函数名  GenCode 		  			*/
/* 功  能  根据给定参数,构造一条中间代码		*/
/* 说  明						*/
/********************************************************/
CodeFile GenCode(String codekind,ArgRecord Arg1,ArgRecord Arg2,ArgRecord Arg3)
{ 
    CodeFile newCode = new CodeFile();
    /*填写代码的内容*/	
    newCode.codeR.codekind = codekind;
    newCode.codeR.arg1 = Arg1;  
    newCode.codeR.arg2 = Arg2;
    newCode.codeR.arg3 = Arg3;
    /*链入中间代码表中*/
    if (firstCode==null)
	firstCode = newCode;
    else
    {	   
        lastCode.next = newCode;
	newCode.former = lastCode;
    }
    lastCode = newCode;

    return newCode;
}
/********************************************************/
/* 函数名  FindField	  				*/
/* 功  能  查找纪录的域名				*/
/* 说  明  返回值为是否找到标志,变量Entry返回此域名在  */
/*	   纪录的域表中的位置.			        */
/********************************************************/
boolean FindField(String Id,FieldChain head,FieldChain Entry)
{ 
    boolean  present=false;
    /*记录当前节点*/
    FieldChain currentItem = head;
    /*从表头开始查找这个标识符,直到找到或到达表尾*/
    while ((currentItem!=null)&&(!present))
    { 
        if  (currentItem.id.equals(Id)) 
	{ 
            present=true;
	    if (Entry!=null)
            {
	        Entry.id=currentItem.id;
                Entry.off=currentItem.off;
                Entry.unitType=currentItem.unitType;
                Entry.next=currentItem.next;
            }
        }
        else  
            currentItem=currentItem.next;
    }
    return present;
}

/****************************************************/
/* 函数名  ConstOptimize			    */
/* 功  能  常表达式优化主函数      		    */
/* 说  明  循环对各个基本块进行常表达式优化	    */
/****************************************************/
CodeFile ConstOptimize()
{    
    /*调用划分基本块函数*/
    blocknum = DivBaseBlock();

    /*循环对每个基本块进行常表达式优化*/
    for (int i=0;i<blocknum;i++)
    {  
        /*基本块入口处置常量定值表为空*/
	table = null;
	/*基本块的常表达式优化*/
        OptiBlock(i);
    }
    /*返回优化后的中间代码*/
    return firstCode;
}
/****************************************************/
/* 函数名  OptiBlock				    */
/* 功  能  对一个基本块进行常表达式优化		    */
/* 说  明					    */
/****************************************************/
void OptiBlock(int i)
{   
    boolean delCode;
    /*指向基本块第一条语句*/
    CodeFile currentCode = baseBlock[i] ;
    CodeFile formerCode;
    CodeFile laterCode;
	    
    ArgRecord arg1;
    ArgRecord arg2;

    /*循环处理每条代码,直到当前基本块结束*/
    while ((currentCode!=baseBlock[i+1])&&(currentCode!=null))
    {   
        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")))
	{ 
            /*算术和关系操作*/ 
	    /*调用算术和关系运算处理函数*/ 
	    delCode = ArithC(currentCode);
	    /*删除标识为真时,删除当前多元式*/
            if (delCode)
	    {  
                formerCode = currentCode.former;
		laterCode = currentCode.next;
		if (formerCode!=null)
		    formerCode.next = laterCode;
		if (laterCode!=null)
		    laterCode.former = formerCode; 
		currentCode = formerCode;
	    }
        }		
        else if (currentCode.codeR.codekind.equals("ASSIG"))
        {
	    /*对第一个ARG结构进行值替换*/
	    SubstiArg(currentCode,1);
	    arg1 = currentCode.codeR.arg1;
	    arg2 = currentCode.codeR.arg2;
	    /*若是常数结构,则将常量定值加入常量定值表*/
	    if (arg1.form.equals("ValueForm"))
		AppendTable(arg2,arg1.midAttr.value);
	    else  /*删除表中含有此变量的定值*/ 
		DelConst(arg2);
	}
        else if (currentCode.codeR.codekind.equals("JUMP0")||currentCode.codeR.codekind.equals("WRITEC"))
	    /*对第一个ARG结构进行值替换*/
	    SubstiArg(currentCode,1);
        else if (currentCode.codeR.codekind.equals("AADD"))
	    /*对第二个ARG结构进行值替换*/
	    SubstiArg(currentCode,2);

	/*令指针指向下一条代码*/
	currentCode = currentCode.next;
    }
}
/****************************************************/
/* 函数名  ArithC				    */
/* 功  能  处理算术操作和关系比较操作		    */
/* 说  明  对运算分量1和运算分量2进行值替换,若都是 */
/*	   常数,将结果写入常量定值表,并置四元式   */
/*	   删除标志为真				    */
/****************************************************/
boolean ArithC(CodeFile code)
{
    boolean delCode = false;
    int value1,value2,result=0;
    /*对分量1进行值替换*/
    SubstiArg(code,1);
    ArgRecord arg1 = code.codeR.arg1;

    /*对分量2进行值替换*/
    SubstiArg(code,2);
    ArgRecord arg2 = code.codeR.arg2;

    String codekind =code.codeR.codekind;
    ArgRecord arg3 = code.codeR.arg3;

    /*操作分量都是常数*/
    if ((arg1.form.equals("ValueForm"))&&(arg2.form.equals("ValueForm")))
    {   
        value1 = arg1.midAttr.value;
	value2 = arg2.midAttr.value;
	if (codekind.equals("ADD"))
            result = value1+value2;
        else if (codekind.equals("SUB"))
            result = value1-value2;
        else if (codekind.equals("MULT"))
            result = value1*value2;
        else if (codekind.equals("DIV"))
            result = value1/value2;	
        else if (codekind.equals("LTC"))
        {   
            if (value1<value2)
		result = 1;
	    else  
                result = 0;
	}
        else if (codekind.equals("EQC"))   
        {
            if (value1==value2)
		result = 1;
	    else 
                result = 0; 
        } 
	/*操作结果写入常量定值表*/
	AppendTable(arg3,result);
	/*当前多元式应删除*/
        delCode = true;
    }
    return delCode;
}
/****************************************************/
/* 函数名  SubstiArg				    */
/* 功  能  对一个ARG结构进行值替换		    */
/* 说  明  参数i指出对中间代码的哪个ARG结构进行替换 */
/****************************************************/
void SubstiArg(CodeFile code,int i)
{   
    ConstDefT Entry=new ConstDefT();
    ArgRecord arg;
    ArgRecord newArg;

    if (i==1)
	arg = code.codeR.arg1;
    else 
        arg = code.codeR.arg2;
    /*若ARG结构是地址类,且常量定值表中有定值,则值替换*/
    if (arg.form.equals("AddrForm"))
    {  
	boolean constflag = FindConstT(arg,Entry);
	if (constflag)
	{ 
            /*创建一个值的ARG结构,替换原有的ARG结构*/
	    newArg = new ArgRecord();
	    newArg.form = "ValueForm";
	    newArg.midAttr.value = Entry.constValue;
	    if (i==1)
		code.codeR.arg1 = newArg;
	    else 
                code.codeR.arg2 = newArg;
        }
    }
}
/****************************************************/
/* 函数名  FindConstT				    */
/* 功  能  在常量定值表中查找当前变量是否有定值	    */
/* 说  明  输入为变量的ARG结构,根据变量是临时变量  */
/*	   还是一般标识符变量,分别处理		    */
/****************************************************/
boolean FindConstT(ArgRecord arg,ConstDefT Entry)
{ 
    boolean present = false;

    int level = arg.midAttr.addr.dataLevel;
    int off = arg.midAttr.addr.dataOff;
	
    ConstDefT t = table;
    while((t!=null)&&(!present))
    {
        if ((t.variable.midAttr.addr.dataLevel==level)
&&(t.variable.midAttr.addr.dataOff==off))
	{	
            present = true;
            /*须逐一赋值,不可直接写为Entry=t*/
            Entry.constValue = t.constValue;
	}
	t = t.next;
    }
    return present;
}
/****************************************************/
/* 函数名  AppendTable				    */
/* 功  能  将变量和其常量值写入常量定值表	

⌨️ 快捷键说明

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