📄 target.java
字号:
{
/*生成else部分入口标号,及其ARG结构*/
int elseL = NewLabel();
ArgRecord ElseLarg=ARGLabel(elseL);
/*生成if语句出口标号,及其ARG结构*/
int outL = NewLabel();
ArgRecord OutLarg = ARGLabel(outL);
/*条件表达式的中间代码生成*/
ArgRecord Earg = GenExpr(t.child[0]);
/*若表达式为假,跳转至else入口标号*/
GenCode("JUMP0",Earg,ElseLarg,null);
/*then部分中间代码生成*/
GenBody(t.child[1]);
/*跳到if出口*/
GenCode("JUMP",OutLarg,null,null);
/*else部分入口标号声明*/
GenCode("LABEL",ElseLarg,null,null);
/*else部分中间代码生成*/
GenBody(t.child[2]);
/*if语句出口标号声明*/
GenCode("LABEL",OutLarg,null,null);
}
/****************************************************/
/* 函数名 GenWhileS */
/* 功 能 循环语句处理函数 */
/* 说 明 将循环入口和出口用不同的中间代码标志,是 */
/* 为了循环不变式外提的需要 */
/****************************************************/
void GenWhileS(TreeNode t)
{
/*生成while语句入口标号,及其ARG结构*/
int inL = NewLabel() ;
ArgRecord InLarg = ARGLabel(inL);
/*生成while语句出口标号,及其ARG结构*/
int outL = NewLabel();
ArgRecord OutLarg = ARGLabel(outL);
/*while语句入口标号声明*/
GenCode("WHILESTART",InLarg,null,null);
/*条件表达式的中间代码生成*/
ArgRecord Earg = GenExpr(t.child[0]);
/*若表达式为假,跳转至while语句出口*/
GenCode("JUMP0",Earg,OutLarg,null);
/*循环体中间代码生成*/
GenBody(t.child[1]);
/*跳到while入口*/
GenCode("JUMP",InLarg,null,null);
/*while出口标号声明*/
GenCode("ENDWHILE",OutLarg,null,null);
}
/********************************************************/
/* 函数名 NewTemp */
/* 功 能 产生一个新的临时变量的ARG结构 */
/* 说 明 临时变量的层数为-1,偏移为编号值,访问方式由 */
/* 参数确定 */
/********************************************************/
ArgRecord NewTemp(String access)
{
ArgRecord newTemp=new ArgRecord();
/*填写临时变量的ARG内容*/
newTemp.form="AddrForm";
newTemp.midAttr.addr=new Addr();
newTemp.midAttr.addr.dataLevel=-1 ;
newTemp.midAttr.addr.dataOff=TempOffset ;
newTemp.midAttr.addr.access=access;
/*临时变量编号加1*/
TempOffset++;
return newTemp;
}
/********************************************************/
/* 函数名 NewLabel */
/* 功 能 产生一个新的标号值 */
/* 说 明 通过全局变量Label加1,产生新的标号值 */
/********************************************************/
int NewLabel()
{
Label++;
return Label;
}
/********************************************************/
/* 函数名 ARGAddr */
/* 功 能 对于给定的变量产生相应的ARG结构 */
/* 说 明 */
/********************************************************/
ArgRecord ARGAddr(String id,int level,int off,String access)
{
ArgRecord arg = new ArgRecord();
/*填写变量ARG结构的内容*/
arg.form = "AddrForm";
arg.midAttr.addr=new Addr();
arg.midAttr.addr.name=id;
arg.midAttr.addr.dataLevel=level;
arg.midAttr.addr.dataOff=off;
arg.midAttr.addr.access=access;
return arg;
}
/********************************************************/
/* 函数名 ARGLabel */
/* 功 能 对于给定的标号产生相应的ARG结构 */
/* 说 明 */
/********************************************************/
ArgRecord ARGLabel(int label)
{
ArgRecord arg = new ArgRecord();
arg.form = "LabelForm";
arg.midAttr.label = label;
return arg;
}
/********************************************************/
/* 函数名 ARGValue */
/* 功 能 对于给定的常数值产生相应的ARG结构 */
/* 说 明 */
/********************************************************/
ArgRecord ARGValue(int value)
{
ArgRecord arg = new ArgRecord();
arg.form = "ValueForm";
arg.midAttr.value = value;
return arg;
}
/********************************************************/
/* 函数名 GenCode */
/* 功 能 根据给定参数,构造一条中间代码 */
/* 说 明 */
/********************************************************/
CodeFile GenCode(String codekind,ArgRecord Arg1,ArgRecord Arg2,ArgRecord Arg3)
{
CodeFile newCode = new CodeFile();
/*填写代码的内容*/
newCode.codeR.codekind = codekind;
newCode.codeR.arg1 = Arg1;
newCode.codeR.arg2 = Arg2;
newCode.codeR.arg3 = Arg3;
/*链入中间代码表中*/
if (firstCode==null)
firstCode = newCode;
else
{
lastCode.next = newCode;
newCode.former = lastCode;
}
lastCode = newCode;
return newCode;
}
/********************************************************/
/* 函数名 FindField */
/* 功 能 查找纪录的域名 */
/* 说 明 返回值为是否找到标志,变量Entry返回此域名在 */
/* 纪录的域表中的位置. */
/********************************************************/
boolean FindField(String Id,FieldChain head,FieldChain Entry)
{
boolean present=false;
/*记录当前节点*/
FieldChain currentItem = head;
/*从表头开始查找这个标识符,直到找到或到达表尾*/
while ((currentItem!=null)&&(!present))
{
if (currentItem.id.equals(Id))
{
present=true;
if (Entry!=null)
{
Entry.id=currentItem.id;
Entry.off=currentItem.off;
Entry.unitType=currentItem.unitType;
Entry.next=currentItem.next;
}
}
else
currentItem=currentItem.next;
}
return present;
}
/****************************************************/
/* 函数名 ConstOptimize */
/* 功 能 常表达式优化主函数 */
/* 说 明 循环对各个基本块进行常表达式优化 */
/****************************************************/
CodeFile ConstOptimize()
{
/*调用划分基本块函数*/
blocknum = DivBaseBlock();
/*循环对每个基本块进行常表达式优化*/
for (int i=0;i<blocknum;i++)
{
/*基本块入口处置常量定值表为空*/
table = null;
/*基本块的常表达式优化*/
OptiBlock(i);
}
/*返回优化后的中间代码*/
return firstCode;
}
/****************************************************/
/* 函数名 OptiBlock */
/* 功 能 对一个基本块进行常表达式优化 */
/* 说 明 */
/****************************************************/
void OptiBlock(int i)
{
boolean delCode;
/*指向基本块第一条语句*/
CodeFile currentCode = baseBlock[i] ;
CodeFile formerCode;
CodeFile laterCode;
ArgRecord arg1;
ArgRecord arg2;
/*循环处理每条代码,直到当前基本块结束*/
while ((currentCode!=baseBlock[i+1])&&(currentCode!=null))
{
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")))
{
/*算术和关系操作*/
/*调用算术和关系运算处理函数*/
delCode = ArithC(currentCode);
/*删除标识为真时,删除当前多元式*/
if (delCode)
{
formerCode = currentCode.former;
laterCode = currentCode.next;
if (formerCode!=null)
formerCode.next = laterCode;
if (laterCode!=null)
laterCode.former = formerCode;
currentCode = formerCode;
}
}
else if (currentCode.codeR.codekind.equals("ASSIG"))
{
/*对第一个ARG结构进行值替换*/
SubstiArg(currentCode,1);
arg1 = currentCode.codeR.arg1;
arg2 = currentCode.codeR.arg2;
/*若是常数结构,则将常量定值加入常量定值表*/
if (arg1.form.equals("ValueForm"))
AppendTable(arg2,arg1.midAttr.value);
else /*删除表中含有此变量的定值*/
DelConst(arg2);
}
else if (currentCode.codeR.codekind.equals("JUMP0")||currentCode.codeR.codekind.equals("WRITEC"))
/*对第一个ARG结构进行值替换*/
SubstiArg(currentCode,1);
else if (currentCode.codeR.codekind.equals("AADD"))
/*对第二个ARG结构进行值替换*/
SubstiArg(currentCode,2);
/*令指针指向下一条代码*/
currentCode = currentCode.next;
}
}
/****************************************************/
/* 函数名 ArithC */
/* 功 能 处理算术操作和关系比较操作 */
/* 说 明 对运算分量1和运算分量2进行值替换,若都是 */
/* 常数,将结果写入常量定值表,并置四元式 */
/* 删除标志为真 */
/****************************************************/
boolean ArithC(CodeFile code)
{
boolean delCode = false;
int value1,value2,result=0;
/*对分量1进行值替换*/
SubstiArg(code,1);
ArgRecord arg1 = code.codeR.arg1;
/*对分量2进行值替换*/
SubstiArg(code,2);
ArgRecord arg2 = code.codeR.arg2;
String codekind =code.codeR.codekind;
ArgRecord arg3 = code.codeR.arg3;
/*操作分量都是常数*/
if ((arg1.form.equals("ValueForm"))&&(arg2.form.equals("ValueForm")))
{
value1 = arg1.midAttr.value;
value2 = arg2.midAttr.value;
if (codekind.equals("ADD"))
result = value1+value2;
else if (codekind.equals("SUB"))
result = value1-value2;
else if (codekind.equals("MULT"))
result = value1*value2;
else if (codekind.equals("DIV"))
result = value1/value2;
else if (codekind.equals("LTC"))
{
if (value1<value2)
result = 1;
else
result = 0;
}
else if (codekind.equals("EQC"))
{
if (value1==value2)
result = 1;
else
result = 0;
}
/*操作结果写入常量定值表*/
AppendTable(arg3,result);
/*当前多元式应删除*/
delCode = true;
}
return delCode;
}
/****************************************************/
/* 函数名 SubstiArg */
/* 功 能 对一个ARG结构进行值替换 */
/* 说 明 参数i指出对中间代码的哪个ARG结构进行替换 */
/****************************************************/
void SubstiArg(CodeFile code,int i)
{
ConstDefT Entry=new ConstDefT();
ArgRecord arg;
ArgRecord newArg;
if (i==1)
arg = code.codeR.arg1;
else
arg = code.codeR.arg2;
/*若ARG结构是地址类,且常量定值表中有定值,则值替换*/
if (arg.form.equals("AddrForm"))
{
boolean constflag = FindConstT(arg,Entry);
if (constflag)
{
/*创建一个值的ARG结构,替换原有的ARG结构*/
newArg = new ArgRecord();
newArg.form = "ValueForm";
newArg.midAttr.value = Entry.constValue;
if (i==1)
code.codeR.arg1 = newArg;
else
code.codeR.arg2 = newArg;
}
}
}
/****************************************************/
/* 函数名 FindConstT */
/* 功 能 在常量定值表中查找当前变量是否有定值 */
/* 说 明 输入为变量的ARG结构,根据变量是临时变量 */
/* 还是一般标识符变量,分别处理 */
/****************************************************/
boolean FindConstT(ArgRecord arg,ConstDefT Entry)
{
boolean present = false;
int level = arg.midAttr.addr.dataLevel;
int off = arg.midAttr.addr.dataOff;
ConstDefT t = table;
while((t!=null)&&(!present))
{
if ((t.variable.midAttr.addr.dataLevel==level)
&&(t.variable.midAttr.addr.dataOff==off))
{
present = true;
/*须逐一赋值,不可直接写为Entry=t*/
Entry.constValue = t.constValue;
}
t = t.next;
}
return present;
}
/****************************************************/
/* 函数名 AppendTable */
/* 功 能 将变量和其常量值写入常量定值表
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -