📄 midcode.cpp
字号:
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 Cmidcode::GenBody(TreeNode *t)
{
TreeNode *t1 = t;
/*令指针指向第一条语句*/
if (t1->nodekind==StmLK)
t1=t1->child[0];
while (t1!=NULL)
{ /*调用语句处理函数*/
GenStatement(t1);
t1= t1->sibling;
}
}
/****************************************************/
/* 函数名 GenStatement */
/* 功 能 语句处理函数 */
/* 说 明 根据语句的具体类型,分别调用相应的 */
/* 语句处理函数 */
/****************************************************/
void Cmidcode::GenStatement(TreeNode *t)
{
switch(t->kind.stmt)
{ case AssignK : GenAssignS(t); break;
case CallK: GenCallS(t); break;
case ReadK: GenReadS(t); break;
case WriteK: GenWriteS(t); break;
case IfK : GenIfS (t); break;
case WhileK: GenWhileS(t); break;
case ReturnK: /*直接生成中间代码*/
GenCode(RETURNC,NULL,NULL,NULL);
break;
default : break;
}
}
/****************************************************/
/* 函数名 GenAssignS */
/* 功 能 赋值语句处理函数 */
/* 说 明 处理左部变量,处理右部表达式,生成 */
/* 赋值语句中间代码 */
/****************************************************/
void Cmidcode::GenAssignS(TreeNode *t)
{ /*调用赋值左部变量的处理函数*/
ArgRecord *Larg = GenVar(t->child[0]);
/*调用赋值右部表达式的处理函数*/
ArgRecord *Rarg = GenExpr(t->child[1]);
/*生成赋值语句中间代码*/
GenCode(ASSIG,Rarg,Larg,NULL);
}
/****************************************************/
/* 函数名 GenVar */
/* 功 能 变量处理 函数 */
/* 说 明 */
/****************************************************/
Cglobal::ArgRecord *Cmidcode::GenVar(TreeNode *t)
{
int low ,size;
fieldChain *head = NULL ;
/*生成变量名的ARG结构, Entry为标识符在符号表中的地址*/
SymbTable *Entry = t->table[0];
ArgRecord *V1arg = ARGAddr(t->name[0],
Entry->attrIR.More.VarAttr.level,
Entry->attrIR.More.VarAttr.off,
Entry->attrIR.More.VarAttr.access);
/*返回的ARG结构*/
ArgRecord * Varg = NULL;
switch(t->attr.ExpAttr.varkind)
{ /*标识符变量情形*/
case IdV: Varg = V1arg; break;
/*数组成员变量情形*/
case ArrayMembV:
/*构造数组下届和数组大小的ARG结构*/
low = Entry->attrIR.idtype->More.ArrayAttr.low;
size = Entry->attrIR.idtype->More.ArrayAttr.elemTy->size;
Varg = GenArray(V1arg, t , low, size);
break;
/*域变量情形*/
case FieldMembV:
head = Entry->attrIR.idtype->More.body;
Varg = GenField(V1arg,t ,head);
break;
default : break;
}
return (Varg);
}
/****************************************************/
/* 函数名 GenArray */
/* 功 能 数组成员变量处理函数 */
/* 说 明 由函数GenVar或函数GenField调用 */
/****************************************************/
Cglobal::ArgRecord *Cmidcode::GenArray(ArgRecord *V1arg,TreeNode *t,int low ,int size)
{ /*处理下标表达式*/
ArgRecord *Earg= GenExpr(t->child[0]);
ArgRecord *lowArg = ARGValue(low);
ArgRecord *sizeArg= ARGValue(size);
/*产生三个临时变量*/
ArgRecord *temp1= NewTemp(dir);
ArgRecord *temp2= NewTemp(dir);
/*注:表示复杂变量的临时变量属于间接访问*/
ArgRecord *temp3= NewTemp(indir);
/*生成中间代码*/
GenCode(SUB, Earg, lowArg ,temp1);
GenCode(MULT,temp1,sizeArg,temp2);
GenCode(AADD,V1arg,temp2, temp3);
return (temp3);
}
/****************************************************/
/* 函数名 GenArray */
/* 功 能 域变量处理函数 */
/* 说 明 由函数GenVar调用 */
/****************************************************/
Cglobal::ArgRecord *Cmidcode::GenField(ArgRecord *V1arg,TreeNode *t ,fieldChain *head )
{
ArgRecord *FieldV = NULL;
/*t1指向当前域成员*/
TreeNode *t1 = t->child[0];
fieldChain *Entry2 = NULL ;
FindField(t1->name[0],head ,&Entry2);
/*域名在域表中的偏移*/
int off = Entry2->off;
ArgRecord *offArg = ARGValue(off);
/*注:表示复杂变量的临时变量属于间接访问*/
ArgRecord *temp1 = NewTemp( indir);
GenCode(AADD , V1arg, offArg , temp1);
/*域是数组变量*/
if (t1->attr.ExpAttr.varkind==ArrayMembV)
{ int low = Entry2->UnitType->More.ArrayAttr.low;
int size= Entry2->UnitType->More.ArrayAttr.elemTy->size;
FieldV = GenArray(temp1, t1,low,size );
}
else /*域是标识符变量*/
FieldV = temp1;
return(FieldV);
}
/****************************************************/
/* 函数名 GenExpr */
/* 功 能 表达式处理函数 */
/* 说 明 */
/****************************************************/
Cglobal::ArgRecord *Cmidcode::GenExpr(TreeNode *t)
{
ArgRecord *arg = NULL;
ArgRecord *Larg = NULL;
ArgRecord *Rarg = NULL;
ArgRecord *temp = NULL;
switch( t->kind.exp)
{ case VariK:
arg = GenVar(t);
break ;
case ConstK:
/*得到值的ARG结构*/
arg = ARGValue(t->attr.ExpAttr.val);
break;
case OpK:
/*处理左部和右部*/
Larg = GenExpr(t->child[0]);
Rarg = GenExpr(t->child[1]);
/*,根据操作符类别,得到中间代码的类别*/
CodeKind op;
switch(t->attr.ExpAttr.op)
{ case LT: op = LTC ; break;
case EQ: op = EQC ; break;
case PLUS: op = ADD ; break;
case MINUS: op = SUB ; break;
case TIMES: op = MULT; break;
case OVER : op = DIV ; break;
default : break;
}
/*产生一个新的临时变量*/
temp = NewTemp(dir);
/*生成中间代码*/
GenCode (op, Larg ,Rarg , temp );
arg = temp ;
break;
default : break;
}
return (arg);
}
/****************************************************/
/* 函数名 GenCall */
/* 功 能 过程调用处理函数 */
/* 说 明 分别调用表达式处理函数处理各个实参,并 */
/* 生成相应的形实参结合中间代码;从符号表中 */
/* 过程标识符属性中,查到入口标号,产生过程 */
/* 调用中间代码 */
/****************************************************/
void Cmidcode::GenCallS(TreeNode *t )
{
/*取得过程标志符在符号表中的地址*/
SymbTable *Entry = t->child[0]->table[0];
ParamTable *param = Entry->attrIR.More.ProcAttr.param;
/*调用表达式处理函数处理各个实参,
并生成相应的形实参结合中间代码*/
TreeNode *t1 = t->child[1];
ArgRecord *Earg = NULL;
while (t1!=NULL)
{ Earg = GenExpr( t1);
/*记录参数的偏移*/
int paramOff = param->entry->attrIR.More.VarAttr.off;
ArgRecord *OffArg = ARGValue(paramOff);
/*形实参结合中间代码*/
if (param->entry->attrIR.More.VarAttr.access==dir)
/*值参结合中间代码*/
GenCode(VALACT, Earg ,OffArg,NULL);
else /*变参结合中间代码*/
GenCode(VARACT, Earg ,OffArg,NULL);
t1 = t1->sibling;
param = param->next;
}
/*过程入口标号及其ARG结构*/
int label = Entry->attrIR.More.ProcAttr.codeEntry;
ArgRecord *labelarg = ARGLabel(label);
/*过程的display表的偏移量*/
int Noff = Entry->attrIR.More.ProcAttr.nOff;
ArgRecord *Noffarg = ARGValue(Noff);
/*生成过程调用中间代码*/
GenCode (CALL,labelarg, NULL,Noffarg);
}
/****************************************************/
/* 函数名 GenReadS */
/* 功 能 读语句处理函数 */
/* 说 明 得到读入变量的ARG结构,生成读语句中间代码*/
/****************************************************/
void Cmidcode::GenReadS(TreeNode *t )
{
SymbTable *Entry = t->table[0];
ArgRecord *Varg = ARGAddr(t->name[0],
Entry->attrIR.More.VarAttr.level,
Entry->attrIR.More.VarAttr.off,
Entry->attrIR.More.VarAttr.access);
/*生成读语句中间代码*/
GenCode(READC,Varg,NULL,NULL);
}
/****************************************************/
/* 函数名 GenWrite */
/* 功 能 写语句处理函数 */
/* 说 明 调用表达式的中间代码生成函数,并产生写 */
/* 语句的中间代码 */
/****************************************************/
void Cmidcode::GenWriteS(TreeNode *t)
{ /*调用表达式的处理*/
ArgRecord *Earg = GenExpr(t->child[0]);
/*生成写语句中间代码*/
GenCode(WRITEC,Earg ,NULL ,NULL);
}
/****************************************************/
/* 函数名 GenIfs */
/* 功 能 条件语句处理函数 */
/* 说 明 */
/****************************************************/
void Cmidcode::GenIfS(TreeNode *t)
{
/*生成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 Cmidcode::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);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -