📄 xunh.java
字号:
package mycompiler.youhua.xunhuan;
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 LoopInfo
{
int state; /*循环状况,为0时表示本层循环不可外提*/
CodeFile whileEntry; /*指向循环入口中间代码*/
int varDef; /*指向本层循环的变量地址表起始处*/
CodeFile whileEnd; /*指向循环出口中间代码*/
}
/*循环信息栈*/
class LoopStack
{
LoopInfo loopInfo;
LoopStack under=null;
}
/********************************************************************/
/* 类 名 Xunh */
/* 功 能 总程序的处理 */
/* 说 明 建立一个类,处理总程序 */
/********************************************************************/
public class Xunh
{
/*临时变量编号,全局变量,每个过程开始都对TempOffset进行
初始化,注:所以,不同过程中,可能有编号相同的临时变量,但是
由于他们互不相干,所以不会有问题;而且优化部分是对基本块进行优化,
每个基本块最大是一个过程,也不会有问题 */
int TempOffset=0;
/*标号值,全局变量*/
int Label=0;
/*指向第一条中间代码*/
CodeFile firstCode;
/*指向当前最后一条中间代码*/
CodeFile lastCode;
/*记录主程序display表的偏移量*/
int StoreNoff;
/*变量定值表,用变量的arg结构表示变量*/
ArgRecord varTable[] = new ArgRecord[100];
int TotalNum = 0;
/*循环信息栈*/
LoopStack loopTop=null;
boolean loopStackEmpty;
CodeFile mid;
public boolean Error=false;
public boolean Error1=false;
public String yerror;
public String serror;
public String midcode;
public Xunh(String s)
{
AnalYuyi a=new AnalYuyi(s);
StoreNoff=a.StoreNoff;
if (a.Error1)
{
Error1=true;
serror=a.serror;
}
else if (a.Error)
{
Error=true;
yerror=a.yerror;
}
else
{
mid=GenMidCode(a.yuyiTree);
LoopOpti();
PrintMidCode(mid);
}
}
/********************************************************/
/* 函数名 GenMidCode */
/* 功 能 中间代码生成主函数 */
/* 说 明 若有过程声明,调用过程声明的代码声明函数; */
/* 调用程序体的代码生成函数 */
/********************************************************/
CodeFile GenMidCode(TreeNode t)
{
/*若有过程声明,调用相应函数,产生过程声明的中间代码*/
TreeNode t1=t.child[1];
while (t1!=null)
{
if (t1.nodekind.equals("ProcDecK"))
GenProcDec(t1);
t1=t1.sibling;
}
/*display表相对于sp的偏移*/
ArgRecord Noff = ARGValue(StoreNoff);
/*生成主程序入口声明代码*/
CodeFile code = GenCode("MENTRY",null,null,Noff);
/*初始化临时变量的开始编号,为临时变量区的第一个地址*/
TempOffset = StoreNoff + 1;
/*调用语句序列的代码生成函数*/
GenBody(t.child[2]);
/*回填主程序的AR的大小到主程序入口中间代码*/
int size = TempOffset;
ArgRecord sizeArg = ARGValue(size);
code.codeR.arg2= sizeArg;
return firstCode;
}
/****************************************************/
/* 函数名 GenProcDec */
/* 功 能 过程声明中间代码生成函数 */
/* 说 明 生成过程入口中间代码,生成过程体的中间 */
/* 代码,生成过程出口的中间代码 */
/****************************************************/
void GenProcDec(TreeNode t)
{
/*得到过程的入口标号*/
int ProcEntry = NewLabel();
/*过程名在符号表中的地址*/
SymbTable Entry = t.table[0];
/*过程入口标号,回填入节点中*/
Entry.attrIR.proc.codeEntry = ProcEntry;
/*过程的display表的偏移量*/
int noff = Entry.attrIR.proc.nOff;
/*得到过程的层数及其ARG结构*/
int procLevel = Entry.attrIR.proc.level;
ArgRecord levelArg = ARGValue(procLevel);
/*若过程内部仍有过程声明,调用相应函数,产生过程声明的中间代码*/
TreeNode t1=t.child[1];
while (t1!=null)
{
if (t1.nodekind.equals("ProcDecK"))
GenProcDec(t1);
t1=t1.sibling;
}
/*产生过程入口中间代码*/
ArgRecord arg1 = ARGLabel(ProcEntry);
CodeFile code = GenCode("PENTRY",arg1,null,levelArg);
/*初始化临时变量的开始编号,为过程临时变量区的第一个地址*/
TempOffset = noff + procLevel+1;
/*调用语句序列的代码生成函数处理过程体*/
GenBody(t.child[2]);
/*得到过程的AR的大小,回填入过程入口中间代码*/
int size = TempOffset;
ArgRecord sizeArg = ARGValue(size);
code.codeR.arg2 = sizeArg;
/*产生过程出口中间代码*/
GenCode("ENDPROC",null,null,null);
}
/****************************************************/
/* 函数名 GenBody */
/* 功 能 语句序列中间代码生成函数 */
/* 说 明 用于处理过程体或者程序体, */
/* 循环处理各个语句 */
/****************************************************/
void GenBody(TreeNode t)
{
TreeNode t1 = t;
/*令指针指向第一条语句*/
if (t1.nodekind.equals("StmLK"))
t1=t1.child[0];
while (t1!=null)
{
/*调用语句处理函数*/
GenStatement(t1);
t1= t1.sibling;
}
}
/****************************************************/
/* 函数名 GenStatement */
/* 功 能 语句处理函数 */
/* 说 明 根据语句的具体类型,分别调用相应的 */
/* 语句处理函数 */
/****************************************************/
void GenStatement(TreeNode t)
{
if (t.kind.equals("AssignK"))
GenAssignS(t);
else if (t.kind.equals("CallK"))
GenCallS(t);
else if (t.kind.equals("ReadK"))
GenReadS(t);
else if (t.kind.equals("WriteK"))
GenWriteS(t);
else if (t.kind.equals("IfK"))
GenIfS (t);
else if (t.kind.equals("WhileK"))
GenWhileS(t);
else if (t.kind.equals("ReturnK")) /*直接生成中间代码*/
GenCode("RETURNC",null,null,null);
}
/****************************************************/
/* 函数名 GenAssignS */
/* 功 能 赋值语句处理函数 */
/* 说 明 处理左部变量,处理右部表达式,生成 */
/* 赋值语句中间代码 */
/****************************************************/
void GenAssignS(TreeNode t)
{
/*调用赋值左部变量的处理函数*/
ArgRecord Larg = GenVar(t.child[0]);
/*调用赋值右部表达式的处理函数*/
ArgRecord Rarg = GenExpr(t.child[1]);
/*生成赋值语句中间代码*/
GenCode("ASSIG",Rarg,Larg,null);
}
/****************************************************/
/* 函数名 GenVar */
/* 功 能 变量处理函数 */
/* 说 明 */
/****************************************************/
ArgRecord GenVar(TreeNode t)
{
int low,size;
FieldChain head;
/*生成变量名的ARG结构, Entry为标识符在符号表中的地址*/
SymbTable Entry = t.table[0];
ArgRecord V1arg = ARGAddr(t.name[0],Entry.attrIR.var.level,
Entry.attrIR.var.off,Entry.attrIR.var.access);
/*返回的ARG结构*/
ArgRecord Varg=null;
if (t.attr.expAttr.varkind.equals("IdV"))
/*标识符变量情形*/
Varg = V1arg;
else if (t.attr.expAttr.varkind.equals("ArrayMembV"))
{
/*数组成员变量情形*/
/*构造数组下届和数组大小的ARG结构*/
low = Entry.attrIR.idtype.array.low;
size = Entry.attrIR.idtype.array.elementTy.size;
Varg = GenArray(V1arg,t,low,size);
}
else if (t.attr.expAttr.varkind.equals("FieldMembV"))
{
/*域变量情形*/
head = Entry.attrIR.idtype.body;
Varg = GenField(V1arg,t,head);
}
return Varg;
}
/****************************************************/
/* 函数名 GenArray */
/* 功 能 数组成员变量处理函数 */
/* 说 明 由函数GenVar或函数GenField调用 */
/****************************************************/
ArgRecord GenArray(ArgRecord V1arg,TreeNode t,int low,int size)
{
/*处理下标表达式*/
ArgRecord Earg= GenExpr(t.child[0]);
ArgRecord lowArg = ARGValue(low);
ArgRecord sizeArg= ARGValue(size);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -