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

📄 translator.java

📁 该文件为编译器解释器的代码
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
/* 过程活动记录头地址指示器sp指向过程活动记录的头地址*/
int sp=6;

/* 过程活动记录尾地址指示器top指向过程活动记录的尾地址 */
int top=5; 

/* 过程活动记录sp到display表距离指示器displayOff */
int displayOff=4;

/* 存储指示器mp指向用于临时变量存储的数据存储器顶端 */
int mp=3;

int ac2=2;      /* 第三累加器 */
int ac1=1;      /* 第二累加器 */
int ac=0;       /* 第一累加器 */

public boolean Error1=false;
public boolean Error=false;
public String yerror;
public String serror;
public String mbcode=" ";

public Target(String s)
{
    Opt o=new Opt(s);
    mainOff=o.mainOff;
    if (o.Error1)
    {
        Error1=true;
        serror=o.serror;
    }
    else if (o.Error)
    {
        Error=true;
        yerror=o.yerror;
    }
    else
        codeGen(o.mid);
}

/************************************************/
/************* 代码生成器的基本函数 *************/
/************************************************/
/* 函数名 codeGen				*/ 
/* 功  能 目标代码生成主函数			*/		
/* 说  明 该函数通过扫描中间代码序列产生目标代码*/
/************************************************/
void codeGen(CodeFile midcode)
{ 
    String s="File: 目标代码";

    /* 生成代码文件说明注释,写入代码文件 */
    emitComment("SNL 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)
    {
	if ((midcode.codeR.codekind.equals("ADD"))||(midcode.codeR.codekind.equals("SUB"))||(midcode.codeR.codekind.equals("MULT"))||(midcode.codeR.codekind.equals("DIV"))||(midcode.codeR.codekind.equals("LTC"))||(midcode.codeR.codekind.equals("EQC")))
	    /*运算处理,包括算术运算和关系运算*/
	    arithGen(midcode);
	else if (midcode.codeR.codekind.equals("AADD"))	
	    /*地址加运算*/
	    aaddGen(midcode);
	else if (midcode.codeR.codekind.equals("READC"))		
	    /*输入语句*/
	    readGen(midcode);		
	else if (midcode.codeR.codekind.equals("WRITEC"))
	    /*输出语句*/
	    writeGen(midcode);		
	else if (midcode.codeR.codekind.equals("RETURNC"))
	    /*返回语句*/
            returnGen(midcode);		
	else if (midcode.codeR.codekind.equals("ASSIG"))
	    /*赋值语句*/
	    assigGen(midcode);		
	else if ((midcode.codeR.codekind.equals("LABEL"))||(midcode.codeR.codekind.equals("WHILESTART"))||(midcode.codeR.codekind.equals("ENDWHILE")))
	    /*标号声明语句*/
	    labelGen(midcode);		
	else if (midcode.codeR.codekind.equals("JUMP"))
	    /*跳转语句*/
	    jumpGen(midcode,1);	
	else if (midcode.codeR.codekind.equals("JUMP0"))
	    /*条件跳转语句*/
	    jump0Gen(midcode);		
	else if (midcode.codeR.codekind.equals("VALACT"))
	    /*形实参结合语句:形参是值参*/
	    valactGen(midcode);
	else if (midcode.codeR.codekind.equals("VARACT"))		
	    /*形实参结合语句:形参是变参*/
	    varactGen(midcode);
	else if (midcode.codeR.codekind.equals("CALL"))		
	    /*过程调用语句*/
	    callGen(midcode);
	else if (midcode.codeR.codekind.equals("PENTRY"))		
	    /*过程入口声明*/
	    pentryGen(midcode);
	else if (midcode.codeR.codekind.equals("ENDPROC"))		
	    /*过程出口声明*/
	    endprocGen(midcode);
	else if (midcode.codeR.codekind.equals("MENTRY"))	
	    /*主程序入口处理*/
	    mentryGen(midcode,savedLoc);
	else 
            mbcode=mbcode+" 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);

    /* 暂存左操作数在ac2中 */
    emitRM("LDA",ac2,0,ac,"op: store  left ");  
  
    /*生成右操作数的目标代码,值存在ac中*/
    operandGen(midcode.codeR.arg2);

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

    /*根据操作符,生成运算的目标代码,ac中为计算结果*/
    if (midcode.codeR.codekind.equals("ADD"))
        /*相加*/
	emitRO("ADD",ac,ac1,ac,"op +");
    else if (midcode.codeR.codekind.equals("SUB"))
	/*相减*/
	emitRO("SUB",ac,ac1,ac,"op -");	
    else if (midcode.codeR.codekind.equals("MULT"))
	/*相乘*/
	emitRO("MUL",ac,ac1,ac,"op *");	
    else if (midcode.codeR.codekind.equals("DIV"))
	/*相除*/
	emitRO("DIV",ac,ac1,ac,"op /");  
    else if (midcode.codeR.codekind.equals("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");
    }
    else if (midcode.codeR.codekind.equals("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");
    }

    /*后面要用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)
{
    if (arg.form.equals("ValueForm"))
    { 
        /*操作数为常数*/
        /* 如果代码生成追踪标志TraceCode为TRUE,写入注释,常数部分开始 */
	if (TraceCode) 
            emitComment("-> Const");

	/* 生成载入常量指令,载入常量到累加器ac */
	emitRM("LDC",ac,arg.midAttr.value,0,"load const");
	  
	/* 如果代码生成追踪标志TraceCode为TRUE,写入注释,常数部分结束 */
	if (TraceCode)  
            emitComment("<- Const");
    }
    else if (arg.form.equals("LabelForm"))
    {
        /*分量为标号*/
	/* 如果代码生成追踪标志TraceCode为TRUE,写入注释,标号部分开始 */
	if (TraceCode) 
            emitComment("-> Label");

	/* 生成载入标号指令,载入标号值到累加器ac */
	emitRM("LDC",ac,arg.midAttr.label,0,"load label");
	  
	/* 如果代码生成追踪标志TraceCode为TRUE,写入注释,标号部分结束 */
	if (TraceCode)  
            emitComment("<- Label");
    } 
    else if (arg.form.equals("AddrForm"))
    {
	/*操作数为变量,有可能是临时变量*/
	/* 如果代码生成追踪标志TraceCode为TRUE,写入注释,标注标识符开始 */
	if (TraceCode) 
            emitComment("-> var");
	  
	FindAddr(arg);
	/*其中ac返回的是源变量或临时变量的绝对偏移*/
	  
	if(arg.midAttr.addr.access.equals("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");
    }
}
/************************************************/
/* 函数名 aaddGen				*/ 
/* 功  能 生成地址加操作的目标代码		*/		
/* 说  明					*/
/************************************************/
void aaddGen(CodeFile midcode)
{	
    /* 如果代码生成追踪标志TraceCode为TRUE,写入注释,aadd语句开始 */
    if (TraceCode)  
        emitComment("->address  add");
  
    if (midcode.codeR.arg1.midAttr.addr.access.equals("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);

    /*地址相加,结果在ac2中*/
    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.midAttr.addr.access.equals("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				*/ 
/* 功  能 生成赋值语句的目标代码		*/		
/* 说  明					*/
/************************************************/
void assigGen(CodeFile midcode)
{
    /* 如果代码生成追踪标志TraceCode为TRUE,写入注释,assign语句开始 */
    if (TraceCode)  
        emitComment("->assign");
    
    /*赋值左部变量的地址,存在ac中*/
    FindAddr(midcode.codeR.arg2);
    /*转放在ac2中*/
    emitRM("LDA",ac2,0,ac,"op: store  addr ");  

    /*生成赋值右部的目标代码,值存在ac中*/
    operandGen(midcode.codeR.arg1);

    if(midcode.codeR.arg2.midAttr.addr.access.equals("dir"))
	/*赋值,ac2中为地址*/
	emitRM("ST",ac,0,ac2,"var assign : store value");
    else
    {
	/*从ac2中取出内容,作为地址*/
	emitRM("LD",ac1,0,ac2," indir var assign");
	emitRM("S

⌨️ 快捷键说明

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