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

📄 target.java

📁 这是编译原理的目标代码生成器java代码
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
package mycompiler.mubiao;
import java.io.*;
import java.awt.*;
import java.util.*;
class TokenType
{ 
    int lineshow;
    String Lex;
    String Sem;
} 
class ChainNodeType  
{
    TokenType  Token=new TokenType();      //单词
    ChainNodeType nextToken=null;          //指向下一个单词的指针
}
/******************************************/
class SymbTable  /* 在语义分析时用到 */
{
    String idName;
    AttributeIR  attrIR=new AttributeIR();
    SymbTable next=null;
}
class AttributeIR
{
    TypeIR  idtype=new TypeIR();
    String kind;	
    Var var;
    Proc proc;
}
class Var
{
    String access;
    int level;
    int off;
    boolean isParam;
}
class Proc
{
    int level;
    ParamTable param;
    int mOff;
    int nOff;
    int procEntry;
    int codeEntry;
}
class ParamTable
{
    SymbTable entry=new SymbTable();
    ParamTable next=null;
}
class TypeIR
{
    int size;
    String kind;
    Array array;
    FieldChain body;
}
class Array
{
    TypeIR indexTy=new TypeIR();
    TypeIR elementTy=new TypeIR();
    int low;
    int up;
}
class FieldChain
{
    String id;
    int off;
    TypeIR unitType=new TypeIR();
    FieldChain next=null;
}
/*******************************************/
class TreeNode   /* 语法树结点的定义 */
{
    TreeNode child[]=new TreeNode[3];
    TreeNode sibling=null;
    int lineno;
    String nodekind;
    String kind;
    int idnum;
    String name[]=new String[10];
    SymbTable table[]=new SymbTable[10];
    Attr attr=new Attr();
}   
class Attr
{
    ArrayAttr arrayAttr=null;  /* 只用到其中一个,用到时再分配内存 */
    ProcAttr procAttr=null;
    ExpAttr expAttr=null;
    String type_name;
}
class ArrayAttr
{
    int low;
    int up;
    String childtype;
}
class ProcAttr
{
    String paramt;
}
class ExpAttr
{
    String op;
    int val;
    String varkind;
    String type;
}
/*源程序对应的中间代码序列表示*/
class CodeFile
{   
    CodeR codeR=new CodeR();
    CodeFile former=null;
    CodeFile next=null;
}
/*中间代码的结构*/
class CodeR
{    
    String codekind;
    ArgRecord arg1;  
    ArgRecord arg2;
    ArgRecord arg3;
}  
class ArgRecord  
{  
    String form;
    MidAttr midAttr=new MidAttr();  /*变量的ARG结构需要纪录的信息*/
}  
class MidAttr		
{  
    int value;  /*纪录整数值*/
    int label;  /*纪录标号的值*/
    Addr addr;
}
class Addr
{ 
    String name;    /*注:变量名字已经没用,这里保留只是为了显示结果清晰*/
    int dataLevel;
    int dataOff;
    String access;  /*类型AccessKind在前面定义*/
}
/*常量定值表,用于常表达式优化*/
class ConstDefT
{ 
    ArgRecord variable=new ArgRecord();   /*用变量的ARG结构表示变量*/
    int constValue;       /*定值*/
    ConstDefT former=null;
    ConstDefT next=null;
} 
/*值编码表ValuNum*/
class ValuNum
{
    ArgRecord arg=new ArgRecord();
    String access;
    CodeInfo codeInfo=new CodeInfo();
    /*指向下一个节点指针*/
    ValuNum next=null;
}
class CodeInfo
{
    int valueCode;   /*直接变量,存储值编码*/
    TwoCode twoCode=null;
}
class TwoCode
{
    int valuecode;
    int addrcode;         /*间接临时变量,存储值编码和地址码*/
}
/*中间代码对应的映象码结构*/
class MirrorCode
{  
    int op1;
    int op2;
    int result;
} 
/*可用表达式代码表UsableExpr*/
class UsableExpr
{ 
    CodeFile code=null;	   /*中间代码地址*/
    MirrorCode mirrorC=null;    /*映象码*/
    UsableExpr next=null;  /*指向下一个节点*/
} 
/*临时变量的等价表TempEqua*/
class TempEqua
{
    ArgRecord arg1=null; /*被替换的临时变量*/
    ArgRecord arg2=null; /*用于替换的临时变量*/
    TempEqua next=null;
} 
/*循环信息表*/
class LoopInfo
{
    int state;            /*循环状况,为0时表示本层循环不可外提*/
    CodeFile whileEntry;  /*指向循环入口中间代码*/
    int varDef;           /*指向本层循环的变量地址表起始处*/
    CodeFile whileEnd;    /*指向循环出口中间代码*/
}    
/*循环信息栈*/
class LoopStack
{ 
    LoopInfo loopInfo;
    LoopStack under=null;
} 
/*标号地址表*/
class LabelAddr
{
    int label;
    int destNum;
    LabelAddr next=null;
} 
/*处理回填地址要用到的数据结构*/
class BackAddr
{  
    int backLoc;
    BackAddr former=null;
}
/*****************************************************/
/********************************************************************/
/* 类  名 Target	                                            */
/* 功  能 总程序的处理					            */
/* 说  明 建立一个类,处理总程序                                    */
/********************************************************************/
public class Target
{
BackAddr AddrTop;
LabelAddr labelAddrT;
int AddrEMPTY;

int tmpOffset = 0;           /*临时变量区的偏移*/

/* TM指令当前生成代码写入地址 */
int emitLoc = 0 ;

/* 用于在函数emitSkip,emitBackup,emitRestore	
   中作为当前最高生成代码写入地址,初始为0 */
int highEmitLoc = 0;

boolean TraceCode=true;    /* 代码生成追踪标志 */

int mainOff;

/* 程序指令指示器pc为7,指向当前指令存储位置	
   程序指示器将使用寄存器数组中的第8个寄存器	*/
int pc=7;	

/* 过程活动记录头地址指示器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);
    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");

⌨️ 快捷键说明

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