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

📄 translator.java

📁 该文件为编译器解释器的代码
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
package mycompiler.jieshiqi;
import java.io.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.applet.*;
/* 指令结构类型:操作码,操作数1,操作数2,操作数3 */
class Instruction
{
    String iop;
    int iarg1;
    int iarg2;
    int iarg3;
} 
/*输入窗口*/
class Mywindow extends Frame
{
    Button button1;
    Label label1,label2;
    TextField text1;
    String stext;

    Mywindow(String s)
    {
	super(s);

	Panel panel1=new Panel(),panel2=new Panel(),panel3=new Panel();
        button1=new Button("确定");
        label1=new Label(s);
        label2=new Label("TM  simulation (enter h for help)...");
        text1=new TextField(10);

	panel1.add(label2);
        panel2.add(label1);
        panel2.add(text1);
	panel3.add(new Label());
	panel3.add(button1);
	panel3.add(new Label());

        setLayout(new GridLayout(3,1));
        add(panel1);
        add(panel2);
        add(panel3);
        setSize(60,70);
        setVisible(false);
        pack();
	
        addWindowListener(new WindowAdapter() 
        {
            public void windowClosing(WindowEvent e)
            {setVisible(false); System.exit(0);}  
        });
    }
}
/*显示窗口*/
class XWindow extends Frame 
{
    TextArea text;
    XWindow(String name,String s)
    {
	super(name);
	setLayout(new GridLayout(1,1));
        text=new TextArea("",50,100);
        text.setText(s);
        add(text);
        setSize(50,100);
	setVisible(false);
	pack();

        addWindowListener(new WindowAdapter() 
        {
            public void windowClosing(WindowEvent e)
            {setVisible(false); System.exit(0);}  
        });
    }
}

/*****************************************************/
/* 类  名 Translator	                             */
/* 功  能 总程序的处理				     */
/* 说  明 建立一个类,处理总程序                     */
/*****************************************************/
public class Translator extends Applet implements ActionListener
{
/***************** 常量 *******************/

/* 为大型程序扩展,指令存储区大小,定义为1024 */
int IADDR_SIZE = 1024;
/* 为大型程序扩展,数据存储区大小,定义为1024 */
int DADDR_SIZE = 1024; 
/* 寄存器数量,定义为8 */
int NO_REGS = 8;
/* PC寄存器,定义为7 */
int PC_REG = 7;
/* 目标代码行大小,定义为121 */
int LINESIZE = 121;
/* 字大小,定义为20 */
int WORDSIZE = 20;

/******** 变量 ********/
int iloc = 0;			/* 指令存储计数指针,初始为0 */
int dloc = 0;			/* 数据存储计数指针,初始为0 */
boolean traceflag = false;	/* 指令执行追踪标志,初始为FALSE */
boolean icountflag = false;	/* 指令执行计数标志,初始为FALSE */

/* iMem用于指令存储,为1024长的指令结构数组 */
Instruction iMem[]=new Instruction[IADDR_SIZE];				

/* dMem用于数据存储,为1024长的整数类型数组 */
int dMem[]=new int[DADDR_SIZE];						

/* reg用于寄存器存储,为8长的整数类型数组 */
int reg[]=new int[NO_REGS];							

/* 指令操作码表,对应寻址模式分为三类,共20个字符串*/
String opCodeTab[ ] = 
{"HALT","IN","OUT","ADD","SUB","MUL","DIV","????",
"LD","ST","????", 
"LDA","LDC","JLT","JLE","JGT","JGE","JEQ","JNE","????"
};
int opRR=7;    /*第一个"????"的位置,它的前面为寄存器寻址模式指令类型*/
int opRM=10;   /*第二个"????"的位置,它的前面为寄存器-内存寻址模式指令类型*/
int opRA=19;   /*第三个"????"的位置,它的前面为寄存器-立即数寻址模式指令类型*/

/** 单步执行结果状态表 **/
//String stepResultTab[] = 
//{"OK","Halted","Instruction Memory Fault","Data Memory Fault","Division by 0"};

String pgm;                     /* 用于存储目标代码 */
char in_Line[]=new char[LINESIZE];  /* 用于存储一行代码 */
int lineLen;		        /* in_Line中代码的长度 */
int inCol;			/* 用于指出在in_Line中的当前字符位置 */
int num;			/* 用于存储当前所得数值 */
String word;	                /* 用于存储当前的字 */
char ch;			/* 当前代码行中当前位置上的字符 */
String name;                    /* 显示窗口的名字 */
String expr="\n";                    /* 显示窗口的内容 */
int in_s;                       /* 在函数actionPerformed与函数stepTM间传递一个int值 */
boolean do_com=true;            /* 输入命令是否为q(退出) */
String stepResult;              /* 结果状态 */
char cmd;		        /* 用户输入命令简称 */
int stepcnt=0;                  /* 执行命令数 */

Mywindow win1;        /* 输入命令窗口 */
Mywindow win2;   /* 输入值窗口 */
XWindow xwin;           /* 显示窗口 */

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

public Translator(String s)
{     
    Target t = new Target(s);
    if (t.Error1)
    {
        Error1=true;
        serror=t.serror;
    }
    else if (t.Error)
    {
        Error=true;
        yerror=t.yerror;
    }
    else
        tmain(t.mbcode);
}

/********************************************/
/* 函数名 tmain			            */
/* 功  能 tm机主执行函数                    */
/* 说  明 函数完成tm机的命令处理,	    */
/*	  并解释执行目标指令	            */
/********************************************/ 
void tmain(String codefile)
{ 
    pgm = codefile;	

    /* 目标代码文件为空,输出错误信息 */
    if (pgm == null)
    { 
        xwin=new XWindow("ERROR","TargetCode file is null");
        xwin.setVisible(true);
        return;
    }								

    /* 读入指令:将指令存储区iMem清空并从指定的文件中写入指令序列 */
    if (!readInstructions())
        return;

    /* 交互执行,处理用户输入的TM命令,对已经输入到iMem中的指令进行操作 */
    enterCom();
}

/********************************************************/
/* 函数名 readInstructions				*/
/* 功  能 指令文件读入函数				*/
/* 说  明 将指令文件中的指令逐条读入到指令存储区iMem	*/
/********************************************************/
boolean readInstructions()
{ 
    int op;		        /* 当前指令操作码在opCodeTab[]中的位置 */
    int arg1=0,arg2=0,arg3=0;		/* 当前指令操作数 */
    int loc,regNo,lineNo;

    /* 将8个寄存器内容初始化为0 */
    for (regNo = 0;regNo < NO_REGS;regNo++)
        reg[regNo] = 0;						

    /* dMem为数据存储区,0地址单元dMem[0]的值赋为数据存储区高端地址1023	*
     * 此数值将在目标程序运行时由程序的先驱指令读入到mp寄存器中	*/
    dMem[0] = DADDR_SIZE - 1;				

    /* 将数据存储数区内除0地址单元外的各单元初始化为0 */
    for (loc = 1;loc < DADDR_SIZE;loc++)
        dMem[loc] = 0;

    /* 将指令存储区中各单元初始化为指令;HALT 0,0,0 */
    for (loc = 0 ; loc < IADDR_SIZE ; loc++)
    { 
        iMem[loc]=new Instruction();
        iMem[loc].iop = "HALT";
        iMem[loc].iarg1 = 0;
        iMem[loc].iarg2 = 0;
        iMem[loc].iarg3 = 0;
    }

    lineNo = 0;		/* lineNo用于记录当前代码指令行号 */

    /*以\n为分隔符,将目标代码分成若干行*/
    StringTokenizer LineCode=new StringTokenizer(pgm,"\n");
    while (LineCode.hasMoreTokens())				
    { 
	String lineTok=LineCode.nextToken();
        lineLen=lineTok.length();
        in_Line=lineTok.toCharArray();

        inCol = 0;		/* 当前代码行in_Line中当前字符位置inCol初始为0 */
        lineNo++;		/* 当前代码行行号加1 */

	/* 当前字符不是"*",即不是注释语句,应该是指令语句 */
        if((nonBlank()) && (in_Line[inCol] != '*'))
        {
	    /* 当前字符不是数字,报地址错,并给出行号lineNo */
	    if (!getNum())
                return error("Bad location",lineNo,-1);

	    /* 将所得数值赋给当前代码地址标号loc */
	    loc = num;

	    /* 代码地址标号loc超出指令存储区地址IADDR_SIZE,报错 */
            if (loc > IADDR_SIZE)
                return error("Location too large",lineNo,loc);

	    /* 代码地址标号loc后面缺少冒号,报缺少冒号错 */
            if (!skipCh(':'))
                return error("Missing colon", lineNo,loc);

	    /* 当前位置不是单词,报缺少指令操作码错 */
            if (!getWord())
                return error("Missing opcode",lineNo,loc);

	    /* 初始查表op,op指向操作码表表首,值为0 */
            op=0;

	    /* 查操作码表opCodeTab,比较当前字word中的字符
               表中共有20个字符串 */
            while ((op < opRA) && (!(word.equals(opCodeTab[op]))))
                op = op+1;

	    /* 当前单词word中指定的操作码不在操作码表opCodeTab中,报非法操作码错误 */
            if(!(word.equals(opCodeTab[op])))
                return error("Illegal opcode",lineNo,loc);

	    /* 对查表得到的操作码值op的寻址模式,进行分类处理 */
            String s_op=opClass(op);
            if(s_op.equals("opclRR"))
            { 			
                /* 寄存器寻址模式操作码 */
	        /* 第一寄存器操作数错,非0-7之间数字,	*
                 * 输出错误信息,行号lineNo,代码地址标号loc	*/
                if ((!getNum()) || (num < 0) || (num >= NO_REGS))
                    return error("Bad first register",lineNo,loc);

		/* 将第一操作数arg1赋值为当前数值num */
                arg1 = num;

		/* 第一操作数后漏掉","分隔符,报错 */
                if (!skipCh(','))
                    return error("Missing comma",lineNo,loc);

		/* 第二寄存器操作数错,非0-7之间数字,		*
		 * 输出错误信息,行号lineNo,代码地址标号loc	*/
                if ((!getNum()) || (num < 0) || (num >= NO_REGS))
                    return error("Bad second register",lineNo,loc);

		/* 将第二个操作数arg2赋值为当前数值num */
		arg2 = num;

		/* 第二操作数后漏掉","分隔符,报错 */
                if (!skipCh(',')) 
                    return error("Missing comma", lineNo,loc);

		/* 第三寄存器操作数错,非0-7之间数字,报错 */
                if ((!getNum()) || (num < 0) || (num >= NO_REGS))
                    return error("Bad third register",lineNo,loc);

		/* 将第三操作数arg3赋值为当前数值num */
                arg3 = num;
            }
            else if((s_op.equals("opclRM"))||(s_op.equals("opclRA")))
            {
		/* 寄存器-内存寻址模式		*
		 * 寄存器-立即数寻址模式	*/
		/* 第一寄存器操作数错,非0-7之间数字,报错 */
                if ((!getNum()) || (num < 0) || (num >= NO_REGS))
                    return error("Bad first register",lineNo,loc);

 		/* 将第一操作数arg1赋值为当前数值num */
		arg1 = num;

		/* 第一操作数后漏掉","分隔符,报错 */
                if (!skipCh(','))
                    return error("Missing comma",lineNo,loc);

		/* 第二偏移地址操作数错误,非数字偏移地址,报错 */
                if (!getNum())
                    return error("Bad displacement",lineNo,loc);

		/* 将第二偏移地址操作数arg2赋值为当前地址num */
                arg2 = num;

		/* 第二偏移地址操作数后漏掉"("或者是","分隔符,报错 */
                if ((!skipCh('(')) && (!skipCh(',')))
                    return error("Missing LParen or comma",lineNo,loc);

		/* 第二寄存器操作数错,非0-7之间数字,报错 */
		if ((!getNum()) || (num < 0) || (num >= NO_REGS))
                    return error("Bad second register",lineNo,loc);

		/* 将第三操作数arg3赋值为当前数值num */
                arg3 = num;
            }
	    /* 按代码地址标号loc将指令存储到指令存储区iMem */
            iMem[loc].iop = opCodeTab[op]; 
            iMem[loc].iarg1 = arg1;
            iMem[loc].iarg2 = arg2;
            iMem[loc].iarg3 = arg3;
        }
    }
    return true;
}  

/****************************************************/
/* 函数名 opClass				    */
/* 功  能 指令寻址模式分类函数			    */
/* 说  明 该函数对给定的指令操作码枚举值c进行分类   */
/*        返回指令所属寻址模式			    */
/****************************************************/
String opClass(int c)
{ 
    /* 如果枚举值c小于opRRLim(7),则指令为寄存器寻址模式指令类型 */
    if(c <= opRR) 
        return "opclRR";

    /* 如果枚举值c小于opRMLim(10),则指令为寄存器-内存寻址模式指令类型 */
    else if(c <= opRM) 
        return "opclRM";

    /* 为寄存器-立即数寻址模式指令类型 */
    else                    
       return "opclRA";
}
 
/****************************************************/
/* 函数名 opNum				            */
/* 功  能 指令寻址模式分类函数			    */
/* 说  明 该函数对给定的指令操作码枚举值c进行分类   */
/*        返回指令所属寻址模式			    */
/****************************************************/
int opNum(String s)
{
    if((s.equals("HALT"))||(s.equals("IN"))||(s.equals("OUT"))||(s.equals("ADD"))||(s.equals("SUB"))||(s.equals("MUL"))||(s.equals("DIV")))
        return 7;
    else if((s.equals("LD"))||(s.equals("ST")))
        return 10;
    else
        return 19;
}
/********************************************************/
/* 函数名 nonBlank				        */
/* 功  能 非空字符获取函数				*/

⌨️ 快捷键说明

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