📄 gongg.java
字号:
midcode=midcode+"EQ";
else if (kind.equals("LTC"))
midcode=midcode+"LT";
else if (kind.equals("READC"))
midcode=midcode+"READ";
else if (kind.equals("WRITEC"))
midcode=midcode+"WRITE";
else if (kind.equals("RETURNC"))
midcode=midcode+"RETURN";
else if (kind.equals("ASSIG"))
midcode=midcode+"ASSIG";
else if (kind.equals("AADD"))
midcode=midcode+"AADD";
else if (kind.equals("LABEL"))
midcode=midcode+"LABEL";
else if (kind.equals("JUMP0"))
midcode=midcode+"JUMP0";
else if (kind.equals("JUMP"))
midcode=midcode+"JUMP";
else if (kind.equals("CALL"))
midcode=midcode+"CALL";
else if (kind.equals("VARACT"))
midcode=midcode+"VARACT";
else if (kind.equals("VALACT"))
midcode=midcode+"VALACT";
else if (kind.equals("PENTRY"))
midcode=midcode+"PENTRY";
else if (kind.equals("ENDPROC"))
midcode=midcode+"ENDPROC";
else if (kind.equals("MENTRY"))
midcode=midcode+"MENTRY";
else if (kind.equals("ENDWHILE"))
midcode=midcode+"ENDWHILE";
else if (kind.equals("WHILESTART"))
midcode=midcode+"WHILESTART";
}
/********************************************************/
/* 函数名 PrintCotent */
/* 功 能 打印ARG结构的内容 */
/* 说 明 由函数PrintOneCode调用 */
/********************************************************/
void PrintContent(ArgRecord arg)
{
if (arg.form.equals("LabelForm"))
midcode=midcode+String.valueOf(arg.midAttr.label);
else if (arg.form.equals("ValueForm"))
midcode=midcode+String.valueOf(arg.midAttr.value);
else if (arg.form.equals("AddrForm"))
{
if (arg.midAttr.addr.dataLevel!=-1)
midcode=midcode+arg.midAttr.addr.name;
else
midcode=midcode+"temp"+String.valueOf(arg.midAttr.addr.dataOff);
}
}
/********************************************************/
/* 函数名 PrintOneCode */
/* 功 能 打印一条中间代码 */
/* 说 明 由函数PrintMidCode调用 */
/********************************************************/
void PrintOneCode(CodeFile code)
{
PrintCodeName(code.codeR.codekind);
midcode=midcode+" ";
if (code.codeR.arg1!=null)
PrintContent(code.codeR.arg1);
else
midcode=midcode+" ";
midcode=midcode+" ";
if (code.codeR.arg2!=null)
PrintContent(code.codeR.arg2);
else
midcode=midcode+" ";
midcode=midcode+" ";
if (code.codeR.arg3!=null)
PrintContent(code.codeR.arg3);
else
midcode=midcode+" ";
}
/********************************************************/
/* 函数名 PrintMidCode */
/* 功 能 打印中间代码序列 */
/* 说 明 */
/********************************************************/
void PrintMidCode(CodeFile firstCode)
{
int i = 0;
CodeFile code = firstCode;
midcode="\n";
while (code!=null)
{
midcode=midcode+String.valueOf(i)+": ";
PrintOneCode(code);
midcode=midcode+"\n";
code = code.next;
i++;
}
}
/****************************************************/
/* 函数名 ECCsave */
/* 功 能 公共表达式优化主函数 */
/* 说 明 循环对各个基本块进行公共表达式优化 */
/****************************************************/
/*注:考虑将blocknum用作局部变量,全局变量封装不好*/
CodeFile ECCsave()
{
blocknum = DivBaseBlock();
/*循环对每个基本块进行公共表达式优化*/
for (int i=0 ;i<blocknum;i++)
{
/*基本块入口处置值编码表,
可用表达式表,临时变量等价表为空*/
valuNumT = null;
usableExprT = null;
tempEquaT = null;
/*基本块的ECC节省*/
SaveInBlock(i);
}
/*返回优化后的中间代码*/
return firstCode;
}
/****************************************************/
/* 函数名 SaveInBlock */
/* 功 能 基本块优化函数 */
/* 说 明 */
/****************************************************/
void SaveInBlock(int i)
{
int op1,op2,op3;
/*指向基本块第一条语句*/
CodeFile currentCode = baseBlock[i];
CodeFile formerCode = null;
CodeFile laterCode = null;
/* 循环处理基本块中的各条语句*/
while ((currentCode!=baseBlock[i+1])&&(currentCode!=null))
{
CodeFile substiCode = new CodeFile();
/*进行等价替换*/
EquaSubsti(currentCode);
if ((currentCode.codeR.codekind.equals("ADD"))||(currentCode.codeR.codekind.equals("SUB"))||(currentCode.codeR.codekind.equals("MULT"))||(currentCode.codeR.codekind.equals("DIV"))||(currentCode.codeR.codekind.equals("LTC"))||(currentCode.codeR.codekind.equals("EQC"))||(currentCode.codeR.codekind.equals("AADD")))
{
/*调用函数Process处理分量1,返回分量1的编码*/
op1 = Process(currentCode,1);
/*调用函数Process处理分量2,返回分量2的编码*/
op2 = Process(currentCode,2);
/*查找可用表达式代码表*/
FindECC(currentCode.codeR.codekind,op1,op2,substiCode);
/*若找到,当前代码可节省*/
if (substiCode.codeR.arg3!=null)
{
/*向临时变量等价表中添加一项*/
AppendTempEqua(currentCode.codeR.arg3,substiCode.codeR.arg3);
/*删除当前代码*/
formerCode = currentCode.former;
laterCode = currentCode.next;
if (formerCode!=null)
formerCode.next = laterCode;
if (laterCode!=null)
laterCode.former = formerCode;
if (formerCode!=null)
currentCode = formerCode;
else
currentCode = laterCode;
}
else /*没找到,代码不可节省*/
{
/*为结果变量构造一个新的编码,填入值编码表*/
Vnumber++;
op3 = Vnumber;
AppendValuNum(currentCode.codeR.arg3,op3);
/*构造对应的映象码*/
MirrorCode mirror = GenMirror(op1,op2,op3);
/*当前代码写入可用表达式代码表*/
AppendUsExpr(currentCode,mirror);
}
}
else if (currentCode.codeR.codekind.equals("ASSIG"))
{
/*Process函数处理赋值右部,返回编码*/
op1 = Process(currentCode,1);
/*若是间接临时变量,op1是地址码;否则,是值码*/
op2 = op1;
/*替换编码表中赋值左部的值编码*/
SubstiVcode(currentCode.codeR.arg2,op2);
/*删除可用表达式代码表中用到赋值左部值编码的项*/
DelUsExpr(currentCode.codeR.arg2);
}
/*处理下一条代码*/
currentCode = currentCode.next;
}
}
/****************************************************/
/* 函数名 EquaSubsti */
/* 功 能 利用临时变量等价表对当前代码进行等价替换 */
/* 说 明 */
/****************************************************/
void EquaSubsti(CodeFile code)
{
TempEqua Entry = new TempEqua();
if (code.codeR.arg1!=null)
/*若操作数1是临时变量,且存在于临时变量等价表中,则替换*/
if (code.codeR.arg1.form.equals("AddrForm"))
if(code.codeR.arg1.midAttr.addr.dataLevel == -1)
{
FindTempEqua(code.codeR.arg1,Entry);
if (Entry.arg2!=null)
code.codeR.arg1 = Entry.arg2;
}
if (code.codeR.arg2!=null)
/*若操作数2是临时变量,且存在于临时变量等价表中,则替换*/
if (code.codeR.arg2.form.equals("AddrForm"))
if (code.codeR.arg2.midAttr.addr.dataLevel == -1)
{
FindTempEqua(code.codeR.arg2,Entry);
if (Entry.arg2!=null)
code.codeR.arg2 = Entry.arg2;
}
}
/****************************************************/
/* 函数名 Process */
/* 功 能 处理操作分量,并返回对应的编码 */
/* 说 明 若首次出现,则分配新编码,填入编码表中, */
/* 返回值取这个新的编码;否则,根据是否间接 */
/* 变量,返回相应的值编码或地址码 */
/****************************************************/
int Process(CodeFile code,int i)
{
ArgRecord arg;
ValuNum Entry = new ValuNum();
String codekind = code.codeR.codekind;
int opC;
if (i==1)
arg = code.codeR.arg1;
else
arg = code.codeR.arg2;
/*若操作数首次出现,则填入编码表*/
SearchValuNum(arg,Entry);
if (Entry.access==null)
{
Vnumber++;
opC = Vnumber; /*op1记录操作数1的值编码*/
AppendValuNum(arg,opC);
}
else
{
/*间接临时变量*/
if (Entry.access.equals("indir"))
/*用间接临时变量的地址码*/
if((codekind.equals("AADD"))||(codekind.equals("ASSIG")))
/*取地址码*/
opC= Entry.codeInfo.twoCode.addrcode;
else /*否则,取值码*/
opC = Entry.codeInfo.twoCode.valuecode;
/*非间接临时变量*/
else
opC = Entry.codeInfo.valueCode;
}
return opC;
}
/****************************************************/
/* 函数名 FindTempEqua */
/* 功 能 查找临时变量等价表 */
/* 说 明 */
/****************************************************/
void FindTempEqua(ArgRecord arg,TempEqua Entry)
{
TempEqua tItem = tempEquaT;
while (tItem!=null)
{ /*注:因为是临时变量,故这里可以直接使用引用比较
而一般变量则不行,因为同一个变量可能会产生
多个内容相同的ARG结构,根据中间代码生成时的
处理手段*/
if (tItem.arg1 == arg)
break;
tItem = tItem.next;
}
if (tItem!=null)
{
Entry.arg1 = tItem.arg1;
Entry.arg2 = tItem.arg2;
Entry.next = tItem.next;
}
}
/****************************************************/
/* 函数名 SearchValuNum */
/* 功 能 查找编码表 */
/* 说 明 若存在于编码表中返回入口地址;否则返回空 */
/****************************************************/
void SearchValuNum(ArgRecord arg,ValuNum Entry)
{
boolean equal = false;
/*指向编码表*/
ValuNum vItem = valuNumT;
while (vItem != null)
{ /*比较是否有相同的变量*/
equal = IsEqual(vItem.arg,arg);
if (equal)
break;
vItem = vItem.next;
}
if (vItem!=null)
{
Entry.arg = vItem.arg;
Entry.access = vItem.access;
Entry.codeInfo = vItem.codeInfo;
Entry.next = vItem.next;
}
}
/****************************************************/
/* 函数名 IsEqual */
/* 功 能 判断两个ARG结构是否相同 */
/* 说 明 这里运算分量没有标号,故只考虑了常量类 */
/* 和地址类ARG结构 */
/****************************************************/
boolean IsEqual(ArgRecord arg1,ArgRecord arg2)
{
boolean equal = false;
/*注:应比较ARG结构内容,不能比较引用,因为一个相同的变量
可能会产生多个相同的ARG结构,由不同的引用,这是
由中间代码生成时的处理策略决定的*/
if (arg1.form == arg2.form)
{
if (arg1.form.equals("ValueForm"))
{/*常数类:值相等则等价*/
if (arg1.midAttr.value == arg2.midAttr.value)
equal = true;
}
/*地址类:层数,偏移,访问方式都相等时等价*/
else if (arg1.form.equals("AddrForm"))
{
if ((arg1.midAttr.addr.dataLevel == arg2.midAttr.addr.dataLevel)
&&(arg1.midAttr.addr.dataOff == arg2.midAttr.addr.dataOff)
&&(arg1.midAttr.addr.access == arg2.midAttr.addr.access))
equal = true;
}
}
return equal;
}
/****************************************************/
/* 函数名 AppendValuNum */
/* 功 能 当前变量及值写入值编码表中 */
/* 说 明 申请一个新节点,根据变量是否为间接临时变 */
/* 填写不同的内容,并联入表中 */
/****************************************************/
void AppendValuNum(ArgRecord arg,int Vcode)
{
/*最后一个节点引用*/
ValuNum last;
/*申请一个新的值编码表的节点,并填写内容*/
ValuNum newItem = new ValuNum();
newItem.arg = arg;
/*若是间接临时变量*/
if ((arg.form.equals("AddrForm"))&&(arg.midAttr.addr.dataLevel == -1)&&(arg.midAttr.addr.access.equals("indir")))
{
newItem.access = "indir";
newItem.codeInfo.twoCode = new TwoCode();
newItem.codeInfo.twoCode.valuecode = Vcode;
newItem.codeInfo.twoCode.addrcode = Vcode;
}
else
{
/*其余情况为:非间接临时变量*/
newItem.access = "dir";
newItem.codeInfo.valueCode = Vcode;
}
/*节点联入值编码表中*/
if (valuNumT == null)
valuNumT = newItem;
else
{
last = valuNumT;
while (last.next!=null)
last = last.next;
last.next = newItem;
}
}
/****************************************************/
/* 函数名 AppendTempEqua */
/* 功 能 将两个等价的临时变量写入临时变量等价表中 */
/* 说 明 表示第一项可以被第二项替换 */
/****************************************************/
void AppendTempEqua(ArgRecord arg1,ArgRecord arg2)
{
/*最后一个节点指针*/
TempEqua last;
/*申请一个新的临时变量等价表的节点,并填写内容*/
TempEqua newItem = new TempEqua();
newItem.arg1 = arg1;
newItem.arg2 = arg2;
/*节点联入临时变量等价表中*/
if (tempEquaT == null)
tempEquaT = newItem;
else
{
last = tempEquaT;
while (last.next!=null)
last = last.next;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -