📄 target.java
字号:
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 + -