现代编译原理--第六章(中间树 IR Tree 含源码)

  (转载请表明出处   http://www.cnblogs.com/BlackWalnut/p/4559717.html )

      这一章,就虎书而言,理论知识点是及其少的,就介绍了为什么要有一个中间表示树。看下面这张图就能理解为什么了。

  由以上可以知道,中间表达式树可以看成是一种简化过的汇编语言组成的树。在这个阶段,我们已经抛弃了所有的变量名称和函数名称,使用标号以及变量以及临时变量(temp_newtemp)来代替来代替。,而且所有的变量都存储在frame中,也就是说,我们是使用frame来分割代码的,一个frame就代表了一个函数。

  这章的代码量却是挺多的。在写代码之前,如果不懂整个代码的布局,是很难了解书上那写代码是对应那些功能,以及书上没有给出的代码,我应该这么完善。那么,我就我自己的理解来说一下到目前为止(翻译成中间表示树以后,编译器的前端就算基本完成了),整个代码的布局是什么样。

  首先我们从外部读取tiger语言编写的源代码,经过由flex和bison生成的lex.yy.cpp  tiger.tab.cpp tiger.tab.h的处理(词法分析,语法分析),生成了抽象语法树,这个语法树的数据结构是在absyn,table,symbol这些文件中定义的。然后我们要抽象语法树转化为中间表示树,这个转化过程都是由 semant 文件中的函数完成(语义分析)。semant主要完成了两个任务:对类型检测(类型检测)以及生成中间表达树(中间表达树)。类型检测过程中使用到了evn,table,symbol,type中定义的一些东西。而转化为中间表示树使用了translate文件中的函数,之所以使用这translate文件 ,是为了将树的具体构建过程和语义分析过程分离,这样如果想要用另一种方式表示中间表示树,可以不动原来semant的代码。因为在semant定义的函数只能看到以Tr_开头的函数,而看不到关于树的任何信息。一棵中间表示树是由frame(F开头),tree(T开头)两部文件分组成的,并且这两部分只被translate使用。

  值得注意的是,前一章我们介绍的活动记录的时候提到,一个活动记录里面包含局部变量,临时变量,寄存器,静态链等信息。但是在frame里面,我们没有记录临时变量。临时变量的信息是在中间表示树中记录的(就是调用temp_newtemp),并且在生成frame的时候,我们也并不是真的取内存中分配一块地址然后记录他的位置,我们只是记录一个变量的相对位移。对于寄存器来说,frame中可以申请无数个寄存器。但是在最终翻译成汇编的时候,我们会根据实际寄存器的数量,将没有办法得到的寄存器的变量放入内存中。而temp_newlabel则是生成各种标签,因为汇编语言中是可以直接goto到一个标签位置的。

  也就是说,frame中记录在任何目标机器上都要用到的信息,这个信息是一个理想化的信息,在最终翻译成代码的时候,还有根据机器的不同来进行调整。

  也要注意到,中间代码多是面向汇编的,所以在translate中将抽象与法树对应的语句和表达式(还是高级语言)转换成中间语法树的节点(面向汇编)。

  知道了以上信息,剩下的就是根据具体的要求来写相应的代码了。可以看出,tiger作者给出的代码框架还是很值得学习的。

     好了,一下就是一部分关键代码。

  

/*
 * tree.h - Definitions for intermediate representation (IR) trees.
 *
 */
#ifndef TREE_H_
#define TREE_H_

typedef struct T_stm_ *T_stm;
typedef struct T_exp_ *T_exp;
typedef struct T_expList_ *T_expList;
struct T_expList_ {T_exp head; T_expList tail;};
typedef struct T_stmList_ *T_stmList;
struct T_stmList_ {T_stm head; T_stmList tail;};

typedef enum {T_plus, T_minus, T_mul, T_div,
    T_and, T_or, T_lshift, T_rshift, T_arshift, T_xor} T_binOp ;

typedef enum  {T_eq, T_ne, T_lt, T_gt, T_le, T_ge,
    T_ult, T_ule, T_ugt, T_uge} T_relOp;

struct T_stm_ {enum {T_SEQ, T_LABEL, T_JUMP, T_CJUMP, T_MOVE,
    T_EXP} kind;
union {struct {T_stm left, right;} SEQ;
Temp_label LABEL;
struct {T_exp exp; Temp_labelList jumps;} JUMP;
struct {T_relOp op; T_exp left, right;
Temp_label trues, falses;} CJUMP;
struct {T_exp dst, src;} MOVE;
T_exp EXP;
} u;
};

struct T_exp_ {enum {T_BINOP, T_MEM, T_TEMP, T_ESEQ, T_NAME,
    T_CONST, T_CALL} kind;
union {struct {T_binOp op; T_exp left, right;} BINOP;
T_exp MEM;
Temp_temp TEMP;
struct {T_stm stm; T_exp exp;} ESEQ;
Temp_label NAME;
int CONST;
struct {T_exp fun; T_expList args;} CALL;
} u;
};

T_expList T_ExpList (T_exp head, T_expList tail);
T_stmList T_StmList (T_stm head, T_stmList tail);

T_stm T_Seq(T_stm left, T_stm right);
T_stm T_Label(Temp_label);
T_stm T_Jump(T_exp exp, Temp_labelList labels);
T_stm T_Cjump(T_relOp op, T_exp left, T_exp right, 
              Temp_label trues, Temp_label falses);
T_stm T_Move(T_exp, T_exp);
T_stm T_Exp(T_exp);

T_exp T_Binop(T_binOp, T_exp, T_exp);
T_exp T_Mem(T_exp);
T_exp T_Temp(Temp_temp);
T_exp T_Eseq(T_stm, T_exp);
T_exp T_Name(Temp_label);
T_exp T_Const(int);
T_exp T_Call(T_exp, T_expList);

T_relOp T_notRel(T_relOp);  /* a op b    ==     not(a notRel(op) b)  */
T_relOp T_commute(T_relOp); /* a op b    ==    b commute(op) a       */



#endif
#include <stdio.h>
#include "util.h"
#include "symbol.h"
#include "temp.h"
#include "tree.h"

T_expList T_ExpList(T_exp head, T_expList tail)
{T_expList p = (T_expList) checked_malloc (sizeof *p);
 p->head=head; p->tail=tail;
 return p;
}

T_stmList T_StmList(T_stm head, T_stmList tail)
{T_stmList p = (T_stmList) checked_malloc (sizeof *p);
 p->head=head; p->tail=tail;
 return p;
}
 
T_stm T_Seq(T_stm left, T_stm right)
{T_stm p = (T_stm) checked_malloc(sizeof *p);
  p->kind= T_stm_::T_SEQ;
 p->u.SEQ.left=left;
 p->u.SEQ.right=right;
 return p;
}

T_stm T_Label(Temp_label label)
{T_stm p = (T_stm) checked_malloc(sizeof *p);
 p->kind= T_stm_::T_LABEL;
 p->u.LABEL=label;
 return p;
}
 
T_stm T_Jump(T_exp exp, Temp_labelList labels)
{T_stm p = (T_stm) checked_malloc(sizeof *p);
 p->kind= T_stm_::T_JUMP;
 p->u.JUMP.exp=exp;
 p->u.JUMP.jumps=labels;
 return p;
}

T_stm T_Cjump(T_relOp op, T_exp left, T_exp right, 
          Temp_label trues, Temp_label falses)
{T_stm p = (T_stm) checked_malloc(sizeof *p);
 p->kind= T_stm_::T_CJUMP;
 p->u.CJUMP.op=op; p->u.CJUMP.left=left; p->u.CJUMP.right=right;
 p->u.CJUMP.trues=trues;
 p->u.CJUMP.falses=falses;
 return p;
}
 
T_stm T_Move(T_exp dst, T_exp src)
{T_stm p = (T_stm) checked_malloc(sizeof *p);
 p->kind= T_stm_::T_MOVE;
 p->u.MOVE.dst=dst;
 p->u.MOVE.src=src;
 return p;
}
 
T_stm T_Exp(T_exp exp)
{T_stm p = (T_stm) checked_malloc(sizeof *p);
 p->kind= T_stm_::T_EXP;
 p->u.EXP=exp;
 return p;
}
 
T_exp T_Binop(T_binOp op, T_exp left, T_exp right)
{T_exp p = (T_exp) checked_malloc(sizeof *p);
 p->kind= T_exp_::T_BINOP;
 p->u.BINOP.op=op;
 p->u.BINOP.left=left;
 p->u.BINOP.right=right;
 return p;
}
 
T_exp T_Mem(T_exp exp)
{T_exp p = (T_exp) checked_malloc(sizeof *p);
 p->kind= T_exp_::T_MEM;
 p->u.MEM=exp;
 return p;
}
 
T_exp T_Temp(Temp_temp temp)
{T_exp p = (T_exp) checked_malloc(sizeof *p);
 p->kind= T_exp_::T_TEMP;
 p->u.TEMP=temp;
 return p;
}
 
T_exp T_Eseq(T_stm stm, T_exp exp)
{T_exp p = (T_exp) checked_malloc(sizeof *p);
 p->kind= T_exp_::T_ESEQ;
 p->u.ESEQ.stm=stm;
 p->u.ESEQ.exp=exp;
 return p;
}
 
T_exp T_Name(Temp_label name)
{T_exp p = (T_exp) checked_malloc(sizeof *p);
 p->kind= T_exp_::T_NAME;
 p->u.NAME=name;
 return p;
}
 
T_exp T_Const(int consti)
{T_exp p = (T_exp) checked_malloc(sizeof *p);
 p->kind= T_exp_::T_CONST;
 p->u.CONST=consti;
 return p;
}
 
T_exp T_Call(T_exp fun, T_expList args)
{T_exp p = (T_exp) checked_malloc(sizeof *p);
 p->kind= T_exp_::T_CALL;
 p->u.CALL.fun=fun;
 p->u.CALL.args=args;
 return p;
}

T_relOp T_notRel(T_relOp r)
{
 switch(r)
   {case T_eq: return T_ne;
    case T_ne: return T_eq;
    case T_lt: return T_ge;
    case T_ge: return T_lt;
    case T_gt: return T_le;
    case T_le: return T_gt;
    case T_ult: return T_uge;
    case T_uge: return T_ult;
    case T_ule: return T_ugt ;
    case T_ugt: return T_ule;
  }
 assert(0); 
}

T_relOp T_commute(T_relOp r)
{switch(r) {
    case T_eq: return T_eq;
    case T_ne: return T_ne;
    case T_lt: return T_gt;
    case T_ge: return T_le;
    case T_gt: return T_lt ;
    case T_le: return T_ge;
    case T_ult: return T_ugt;
    case T_uge: return T_ule;
    case T_ule: return T_uge ;
    case T_ugt: return T_ult;
   }
 assert(0); 
}
#ifndef TRANSLATE_H_
#define TRANSLATE_H_

#include "frame.h"
#include "absyn.h"
//frame œ‡πÿ

typedef struct Tr_level_      * Tr_level ;    
typedef struct Tr_accesslist_ * Tr_accesslist ;
typedef struct Tr_access_     * Tr_access ;  
struct  Tr_accesslist_  { Tr_access  head ;  Tr_accesslist tial ; };
struct  Tr_level_       { Tr_level parent ;  F_frame frame; };  //≤„µƒ◊˜”√ «Œ™¡À±£¥Êæ≤è¡¥
struct  Tr_access_      { Tr_level level  ;  F_access access ; };//º«¬º¡À“ª∏ˆ≤„∫Õ≤„÷–µƒŒª÷√ ’‚—˘ ∑Ω±„“ª∏ˆ«∂Ã◊≤„»•≤È—Ø“˝”√µƒÕ‚≤ø±‰¡ø À¸ «E_varEntry÷–µƒ“ª∏ˆ±‰¡ø


//frame œ‡πÿ
Tr_accesslist Tr_Accesslist(Tr_access head , Tr_accesslist tial) ;
Tr_access Tr_Access(Tr_level level , F_access access ) ;
Tr_level Tr_outermorst() ;
Tr_level Tr_newLevel(Tr_level parent , Temp_label name , U_boolList formals ) ;
Tr_accesslist Tr_formals(Tr_level level) ;
Tr_access Tr_allocLocal(Tr_level level , bool escape ) ;
void     Tr_ClearAcces(Tr_accesslist list) ; //Ω´list Õ∑≈ µ´ « ≤ª Õ∑≈∆‰÷–µƒhead



// IR Tree œ‡πÿ
#define  GetExpEx  Tr_exp_::Tr_ex
#define  GetExpNx  Tr_exp_::Tr_nx 
#define  GetExpCx  Tr_exp_::Tr_cx 

typedef struct Tr_exp_* Tr_exp ;
typedef struct Tr_expList_ * Tr_expList ;
typedef struct patchList_ * patchList ;

struct Cx { patchList trues ; patchList falses ; T_stm stm ; };
struct patchList_ { Temp_label *head ; patchList tail ; };

struct Tr_exp_
{
    enum{Tr_ex , Tr_nx , Tr_cx } kind;
    union
    {
        T_exp ex ;
        T_stm nx ;
        Cx    cx ;
    }u;
};

struct Tr_expList_
{
    Tr_exp head ;
    Tr_expList tail ;
};

//IR Treeœ‡πÿ 
Tr_exp Tr_Ex(T_exp exp ) ;
Tr_exp Tr_Nx(T_stm stm ) ;
Tr_exp Tr_Cx(patchList trues , patchList falses , T_stm stm ) ;

T_exp  Tr_unEx(Tr_exp exp) ;
T_stm  Tr_unNx(Tr_exp exp) ;
Cx     Tr_unCx(Tr_exp exp) ;

patchList PatchList(Temp_label *head , patchList patchlist ) ;
void doPatch(patchList patchlist , Temp_label label) ;
Tr_expList Tr_ExpList(Tr_exp head , Tr_expList tail) ;

Tr_exp  Tr_nilExp() ;
Tr_exp  Tr_intExp(int i) ;
Tr_exp  Tr_stringExp(string str) ;

Tr_exp  Tr_simpleVar(Tr_access acc , Tr_level level );
Tr_exp  Tr_subscriptVar(Tr_exp base, Tr_exp index);
Tr_exp  Tr_fieldVar(Tr_exp base, int offset);

Tr_exp  Tr_binopExp(Tr_exp left , Tr_exp right ,A_oper oper );
Tr_exp  Tr_relopExp(Tr_exp left , Tr_exp right , A_oper oper) ;

Tr_exp Tr_ifExp( Tr_exp test , Tr_exp then , Tr_exp elses ) ;
Tr_exp Tr_recordExp( Tr_expList explist , int num) ;
Tr_exp Tr_arryExp(Tr_exp index , Tr_exp init) ;
Tr_exp Tr_seqExp(Tr_expList explist) ;
Tr_exp Tr_assignExp(Tr_exp exp1 , Tr_exp exp2) ;

Tr_exp Tr_whileExp(  Tr_exp test , Tr_exp body , bool isbreak) ;
Tr_exp Tr_forExp(Tr_access acc , Tr_exp hi , Tr_exp low , Tr_exp body) ;
Tr_exp Tr_breakExp() ;
Tr_exp Tr_letExp(Tr_expList declist , Tr_exp exp ) ;

Tr_exp Tr_callExp(Temp_label label ,Tr_level funleve , Tr_level  level ,Tr_expList explist ) ;
Tr_exp Tr_StaticLink(Tr_level now, Tr_level def);


Tr_exp Tr_varDec(Tr_access acc , Tr_exp init) ;
Tr_exp Tr_typeDec();
Tr_exp Tr_funDec(Tr_expList bodylist) ;

void Tr_procEntryExit(Tr_level level , Tr_exp body , Tr_accesslist formals) ;

F_fragList Tr_getResult() ;

#endif
#include "translate.h"
#include "util.h"
#include "env.h"
#include <stdio.h>
#include <stdlib.h>
Tr_access Tr_allocLocal(Tr_level level , bool escape )
{
  F_access acc ;
  acc = F_allocLoacl(level->frame  , escape) ;
  return Tr_Access(level , acc) ;
}

Tr_access Tr_Access(Tr_level level , F_access access )
{
    Tr_access acc = (Tr_access)checked_malloc(sizeof(*acc));
    acc->level = level;
    acc->access = access;
    return acc;
}

Tr_accesslist Tr_Accesslist(Tr_access head , Tr_accesslist tial)
{
    Tr_accesslist tmp = (Tr_accesslist)checked_malloc(sizeof(*tmp));
    tmp->head = head ;
    tmp->tial = tial ;
    return tmp ;
}
Tr_level Tr_newLevel(Tr_level parent , Temp_label name , U_boolList formals )
{
    Tr_level level = (Tr_level)checked_malloc(sizeof(*level));
    level->parent = parent ;
    level->frame = F_newframe(name , U_BoolList(true , formals) ) ; // ’‚¿Ôº”µƒtrue¥˙±Ì¡Àæ≤è¡¥
    return level ;
}


Tr_accesslist Tr_formals(Tr_level level)
{
    F_accesslist f_acc = level->frame->formals ;
    f_acc = f_acc->tail ;//µ⁄“ª∏ˆ¥˙±Ì¡Àæ≤è¡¥ À˘“‘“™ÃÙ≥ˆ¿¥
    Tr_accesslist tmp = NULL ;
    while(f_acc)
    {
         tmp = Tr_Accesslist(Tr_Access(level , f_acc->head), tmp) ;
         f_acc = f_acc->tail ;
    }
    return tmp ;
}

Tr_level Tr_outermorst()
{
    static Tr_level tmp = NULL ;
    if (!tmp)
    {
        tmp = (Tr_level)checked_malloc(sizeof(*tmp));
        U_boolList b = U_BoolList(true , NULL) ;
        tmp->frame = F_newframe(Temp_newlabel() , b)  ;
        tmp->parent = NULL ;
    }
    return tmp ;

}

void Tr_ClearAcces(Tr_accesslist list)
{
    Tr_accesslist tmp ;
    tmp = list ;
    while(list)
    {
        list = list->tial ;
        tmp->head =  NULL ;
        tmp->tial =  NULL ;
        free(tmp) ;
        tmp = list ;
    }
}

Tr_exp Tr_Ex(T_exp exp )
{
    Tr_exp tmp = (Tr_exp)checked_malloc(sizeof(*tmp));
    tmp->kind = GetExpEx ;
    tmp->u.ex = exp ;
    return tmp ;
}

Tr_exp Tr_Nx(T_stm stm )
{
    Tr_exp tmp = (Tr_exp)checked_malloc(sizeof(*tmp));
    tmp->kind = GetExpNx ;
    tmp->u.nx = stm ;
    return tmp ;
}

Tr_exp Tr_Cx(patchList trues , patchList falses , T_stm stm )
{
    Tr_exp tmp = (Tr_exp)checked_malloc(sizeof(*tmp));
    tmp->kind = GetExpCx ;
    tmp->u.cx.falses = falses ;
    tmp->u.cx.trues = trues ;
    tmp->u.cx.stm = stm ;
    return tmp ;
}
T_stm  Tr_unNx(Tr_exp exp)
{
    switch (exp->kind)
    {
    case  GetExpEx:
        return T_Exp(exp->u.ex);
    case  GetExpCx:
        return T_Exp(Tr_unEx(exp));
    case  GetExpNx:
        return exp->u.nx;
    }
    assert(0);
}
Cx  Tr_unCx(Tr_exp exp)
{
    switch (exp->kind)
    {
    case GetExpCx :
        return exp->u.cx;
    case GetExpEx:
        {
            T_stm stm = T_Cjump(T_ne, exp->u.ex, T_Const(0), NULL ,  NULL);
            Cx cx; 
            cx.stm = stm;
            cx.falses = PatchList(&stm->u.CJUMP.falses, NULL);
            cx.trues = PatchList(&stm->u.CJUMP.trues, NULL);
            return cx;
        }
    }
    assert(0);
}
T_exp  Tr_unEx(Tr_exp exp)
{
    switch(exp->kind)
    {
    case GetExpEx :
     return exp->u.ex ;
    case GetExpCx :
        {
          Temp_temp tmp = Temp_newtemp() ;
          Temp_label t = Temp_newlabel() , f = Temp_newlabel() ;
          doPatch(exp->u.cx.falses , f) ;
          doPatch(exp->u.cx.trues , t) ;
          return T_Eseq(T_Move(T_Temp(tmp) , T_Const(1)),
                  T_Eseq( exp->u.cx.stm ,
                   T_Eseq( T_Label(f) ,
                    T_Eseq(T_Move(T_Temp(tmp) , T_Const(0)) ,
                     T_Eseq(T_Label(t) ,
                      T_Temp(tmp)))))) ;

        }
    case GetExpNx :
        {
          return T_Eseq(exp->u.nx, T_Const(0));// Œ™ ≤√¥“™∑µªÿ0 ’‚∏ˆnx≤ª «Œfi÷µ”Ôæ‰√¥
        }
    }
    assert(0);
}

void doPatch(  patchList patchlist , Temp_label lable)
{
    for ( ;  patchlist ; patchlist = patchlist->tail)
    {
        (*patchlist->head) = lable ;
    }
}

patchList PatchList(Temp_label *head , patchList patchlist ) 
{
    patchList tmp = (patchList)checked_malloc(sizeof(*tmp));
    tmp->head = head ;
    tmp->tail = patchlist ;
    return tmp ;
}

Tr_expList Tr_ExpList(Tr_exp head , Tr_expList tail)
{
    Tr_expList tmp = (Tr_expList)checked_malloc(sizeof(*tmp)) ;
    tmp->head = head ;
    tmp->tail = tail ;
    return tmp ;
}

Tr_exp Tr_nilExp()
{
    static Temp_temp temp =  NULL  ;
        if ( !temp )
        {
           temp = Temp_newtemp() ;
           T_stm alloc = T_Move(T_Temp(temp),
               T_Call(T_Name(Temp_namedlabel("initRecord")), T_ExpList(T_Const(0), NULL)));
           return Tr_Ex(T_Eseq(alloc, T_Temp(temp)));
        }

     return Tr_Ex(T_Temp(temp)) ;
}

Tr_exp Tr_intExp(int i)
{
    return  Tr_Ex(T_Const(i)) ;
}

static F_fragList stringFragList = NULL;
Tr_exp Tr_stringExp(string s) 
{ 
    Temp_label slabel = Temp_newlabel();
    F_frag fragment = F_StringFrag(slabel, s);
    stringFragList = F_FragList(fragment, stringFragList);
    return Tr_Ex(T_Name(slabel));
}

Tr_exp Tr_simpleVar(Tr_access acc, Tr_level level)
{
    T_exp tmp = T_Temp(F_FP());
    while ( level && level != acc->level->parent )
    {
        tmp = T_Mem(T_Binop(T_plus, T_Const(level->frame->formals->head->u.offset), tmp));
        level = level->parent;
    }
    
    return  Tr_Ex(F_Exp(acc->access, tmp));
}

Tr_exp Tr_subscriptVar(Tr_exp base, Tr_exp index )
{
    return Tr_Ex(T_Mem(T_Binop(T_plus, Tr_unEx(base), T_Binop(T_mul, Tr_unEx(index), T_Const(F_wordSize)))));
}

Tr_exp Tr_fieldVar(Tr_exp base, int offset)
{
    return Tr_Ex(T_Mem(T_Binop(T_plus, Tr_unEx(base), T_Const(offset * F_wordSize))));
}

Tr_exp Tr_binopExp(Tr_exp left , Tr_exp right ,A_oper oper )
{
    T_binOp op ;
    switch(oper)
    {
    case A_plusOp   :
        {
            op = T_binOp::T_plus ;
            break ;
        }
    case A_minusOp  :
        {
            op = T_binOp::T_minus ;
            break ;
        }
    case A_timesOp  :
        {
            op = T_binOp::T_mul ;
            break ;
        }
    case A_divideOp :
        {
            op = T_binOp::T_div ;
            break ;
        }
    default :
        {
            return NULL ;
        }
    }
   return Tr_Ex(T_Binop(op , Tr_unEx(left) , Tr_unEx(right))) ;
}
Tr_exp  Tr_relopExp(Tr_exp left , Tr_exp right , A_oper oper) 
{
    T_relOp op ;
    switch(oper)
    {
     case A_ltOp :
         {
             op = T_relOp::T_lt ;
             break ;
         }
     case A_leOp :
         {
             op = T_relOp::T_le ;
             break ;
         }
     case A_gtOp :
         {
             op = T_relOp::T_gt ;
             break ;
         }
     case A_geOp :
         {
              op = T_relOp::T_ge ;
             break ;
         }
     case A_eqOp :
         {
             op = T_relOp::T_eq ;
             break ;
         }
     case A_neqOp :
         {
             op = T_relOp::T_ne ;
             break ;
         }
     default :
         return NULL ;
    }
    T_stm stm = T_Cjump(op ,Tr_unEx(left) , Tr_unEx(right) , NULL , NULL );
    patchList trues =  PatchList(&stm->u.CJUMP.trues , NULL) ;
    patchList falses =  PatchList(&stm->u.CJUMP.falses , NULL) ;
    return  Tr_Cx(trues , falses , stm) ;
}

Tr_exp Tr_ifExp( Tr_exp test , Tr_exp then , Tr_exp elses ) 
{

   Cx ctest  = Tr_unCx(test) ;
   T_stm reslutstm , thenstm , elsestm  ;
   reslutstm = thenstm = elsestm = NULL ;
   Temp_label t = Temp_newlabel() ;
   Temp_label f = Temp_newlabel() ;
   Temp_temp v = Temp_newtemp() ; 
    doPatch(ctest.falses , f) ;
    doPatch(ctest.trues , t ) ; 
        switch(then->kind)
        {
        case GetExpEx :
            {
                thenstm = T_Seq(ctest.stm , T_Seq(T_Label(t) , T_Move(T_Temp(v) , Tr_unEx(then)))) ;
                break ;
            }
        case GetExpNx :
            {
                thenstm = T_Seq(ctest.stm ,T_Seq(T_Label(t) , then->u.nx)) ;
                break ;
            }
        case GetExpCx :
            {
                
                thenstm = T_Seq(ctest.stm , T_Seq(T_Label(t) , Tr_unNx(then))) ;
                break ;
            }
        }

   if (elses)
   {
       switch(elses->kind)
       {
       case GetExpEx:
           {
               elsestm = T_Move(T_Temp(v), Tr_unEx(elses)) ;
               break ;
           }
       case GetExpNx :
           {
               elsestm = elses->u.nx ;
               break ;
           }
       case GetExpCx :
           {
              elsestm = Tr_unNx(elses) ;
              break ;
           }
       }
   }
   if (elsestm)
   {
       Temp_label jump = Temp_newlabel() ;
       
       return Tr_Nx(T_Seq(
           T_Seq( thenstm , T_Seq(T_Jump( T_Name(jump) , Temp_LabelList(jump , NULL)) ,T_Seq(T_Label(f) ,elsestm))) ,
           T_Label(jump))) ;
   }
        return Tr_Nx( T_Seq(thenstm , T_Label(f))) ; 
}

Tr_exp Tr_recordExp( Tr_expList explist , int num)  //’‚¿Ô¥´Ω¯¿¥µƒexplist ∫Õ’Ê «µƒexplist «œ‡∑¥µƒ
{
   T_stm stm ;
   Temp_temp t = Temp_newtemp();
   T_exp callfun = T_Call(T_Name(Temp_namedlabel("initRecord")) ,T_ExpList(T_Const(num*F_wordSize) , NULL)) ;

   stm = T_Move(T_Mem(T_Binop(T_plus , T_Temp(t) , T_Const((num - 1)*F_wordSize))), Tr_unEx(explist->head)) ;
   num-- ;
   explist = explist->tail ;
   while(explist)
   {
     stm = T_Seq(T_Move(T_Mem(T_Binop(T_plus, T_Temp(t) , T_Const((num -1 ) * F_wordSize))), Tr_unEx(explist->head)),stm) ;
     explist = explist->tail ;
     num-- ;
   }
   stm = T_Seq(T_Move(T_Temp(t) , callfun) , stm) ;
   return Tr_Ex( T_Eseq( stm , T_Temp(t))) ;
}


Tr_exp Tr_arryExp(Tr_exp index , Tr_exp init)
{
    Temp_temp t = Temp_newtemp() ;
    T_exp callfun = T_Call(T_Name(Temp_namedlabel("initArray")) ,T_ExpList( Tr_unEx(index),T_ExpList(Tr_unEx(init) ,NULL))) ;
    return  Tr_Nx( T_Move( T_Temp(t) , callfun) );
}
 
Tr_exp Tr_seqExp(Tr_expList explist)
{
    if (!explist)
    {
        return NULL ;
    }
    T_stm stm = Tr_unNx(explist->head) ;
    explist = explist->tail ;
    while(explist)
    {
        stm = T_Seq( Tr_unNx(explist->head) , stm) ;
        explist = explist->tail ;
    }
    return Tr_Nx(stm) ;
}

Tr_exp Tr_assignExp(Tr_exp exp1 , Tr_exp exp2)
{
    return Tr_Nx(T_Move(T_Mem( Tr_unEx(exp1)) , T_Mem(Tr_unEx(exp2))))  ;
}

Tr_exp Tr_letExp(Tr_expList declist , Tr_exp exp )
{
    if (!declist)
    {
        return NULL ;
    }
    T_stm stm = Tr_unNx(declist->head) ;
    declist = declist->tail ;
    while(declist)
    {
        stm = T_Seq(Tr_unNx(declist->head) , stm) ;
        declist = declist->tail ;
    }
    if (exp)
    {
        stm = T_Seq(stm , Tr_unNx(exp)) ;
    }
    return Tr_Nx(stm);
}

Tr_exp Tr_whileExp(Tr_exp test , Tr_exp body , bool isbreak)
{
  
    Cx ctest = Tr_unCx(test) ;
    Temp_label t = Temp_newlabel() ;
    Temp_label done = Temp_namedlabel("done") ;
    doPatch(ctest.falses , done) ;
    doPatch(ctest.trues , t) ;
    T_stm  stm ;
    Temp_label testlabel = Temp_newlabel();
    
    stm = T_Seq(T_Label(t) , T_Seq(Tr_unNx(body) ,T_Jump(T_Name(testlabel),Temp_LabelList(testlabel,NULL)))) ;
    stm = T_Seq( T_Label(testlabel) , T_Seq(ctest.stm ,T_Seq(stm , T_Label(done)))) ;
    return Tr_Nx(stm);
}

Tr_exp Tr_breakExp()
{
    Temp_label done = Temp_namedlabel("done") ;
    return Tr_Nx(T_Jump(T_Name(done) , Temp_LabelList(done , NULL))) ;
}

Tr_exp Tr_forExp(Tr_access acc , Tr_exp hi , Tr_exp low , Tr_exp body)
{
    T_exp tmp = T_Temp(F_FP());
     //tmp = T_Mem(T_Binop(T_plus ,tmp , T_Const(acc->level->frame->formals->head->u.offset))) ;
      T_exp memt =  F_Exp(acc->access , tmp) ;
    T_stm stm = T_Move(memt , Tr_unEx(low)) ;
    Temp_temp h = Temp_newtemp() ;
    T_stm limit = T_Move(T_Temp(h) , Tr_unEx(hi)) ;
    Cx cx ;
    cx.stm =  T_Cjump(T_lt ,memt ,T_Temp(h) , NULL , NULL) ;
    cx.falses = PatchList(&cx.stm->u.CJUMP.falses , NULL) ;
    cx.trues = PatchList(&cx.stm->u.CJUMP.trues , NULL) ;
    T_stm finalbody = T_Seq(T_Move(memt , T_Binop(T_plus , memt , T_Const(1))) , Tr_unNx(body)) ;
    
    Tr_exp tmpwhile = Tr_whileExp(Tr_Cx(cx.trues , cx.falses , cx.stm) , Tr_Nx(finalbody) , false) ;
    return  Tr_Nx(T_Seq( stm , T_Seq( limit , Tr_unNx(tmpwhile)))) ;
}
 Tr_exp Tr_StaticLink(Tr_level now, Tr_level def)
 {
    T_exp addr = T_Temp(F_FP());
    while(now && (now != def->parent)) 
    { 
        F_access sl = F_formals(now->frame)->head;
        addr = F_Exp(sl, addr);
        now = now->parent;
    }
    return Tr_Ex(addr);
}
Tr_exp Tr_callExp(Temp_label label ,Tr_level funleve , Tr_level  level ,Tr_expList explist ) 
{
    T_expList tmplist = NULL;
    while(explist)
    {
        tmplist = T_ExpList( Tr_unEx(explist->head) , tmplist) ;
        explist = explist->tail ;
    }
    tmplist = T_ExpList(Tr_unEx(Tr_StaticLink(funleve , level)) , tmplist) ;
    T_exp callfun = T_Call(T_Name(label) ,tmplist) ;
    return Tr_Ex(callfun) ;
}
Tr_exp Tr_callExp(E_enventry entry , Tr_level level , Tr_expList explist  ) 
{
    
     T_expList tmplist = NULL;
     while(explist)
     {
         tmplist = T_ExpList( Tr_unEx(explist->head) , tmplist) ;
         explist = explist->tail ;
     }
     tmplist = T_ExpList(Tr_unEx(Tr_StaticLink(entry->u.fun.level , level)) , tmplist) ;
    T_exp callfun = T_Call(T_Name(entry->u.fun.label) ,tmplist) ;
    return Tr_Ex(callfun) ;
}

Tr_exp Tr_varDec(Tr_access acc , Tr_exp init)
{
    T_exp tmp = T_Temp(F_FP());
    T_exp memt =  F_Exp(acc->access , tmp) ;
    return Tr_Nx(T_Move(memt , Tr_unEx(init)))  ;
}

Tr_exp Tr_typeDec()
{
     return Tr_Ex(T_Const(0)) ;
}

Tr_exp Tr_funDec(Tr_expList bodylist)
{
    T_stm stm ;
    stm = T_Move(T_Temp(F_RV()) , Tr_unEx(bodylist->head)) ;
    bodylist = bodylist->tail ;
    while (bodylist)
    {
      stm = T_Seq(T_Move(T_Temp(F_RV()) , Tr_unEx(bodylist->head)) , stm);
    }
    return Tr_Nx(stm) ;
}
#ifndef SENMANT_H_
#define SENMANT_H_
#include "types.h"
#include "translate.h"
#include "absyn.h"
struct expty { Tr_exp exp ; Ty_ty ty; };
expty expTy(Tr_exp exp , Ty_ty ty) ;
expty  transVar(S_table venv , S_table tenv , A_var var , Tr_level level) ;
expty  transExp(S_table venv , S_table tenv , A_exp exp , Tr_level level  ) ; //∑µªÿ÷µ÷–µƒtyty“ª∂® «◊ÓµÕ≤„µƒ¿‡–Õ
Tr_exp   transDec(S_table venv , S_table tenv , A_dec dec , Tr_level level ) ;
Ty_ty  transTy( S_table tenv , A_ty ty) ;
//ƒ⁄÷√±Í æ∑˚ºÏ≤‚ int string ÷ª”√‘⁄œÚ÷µª∑æ≥ ‰»Î÷µµƒ ±∫Ú≤≈ºÏ≤‚  ¿‡–Õª∑æ≥‘⁄ tranTy÷–“—æ≠ºÏ≤‚
bool  innerIdentifiers( S_symbol sym);
#endif
#include "semant.h"
#include <assert.h>
#include "env.h"

expty expTy(Tr_exp exp , Ty_ty ty)
{
    expty e ;
    e.exp = exp ; e.ty = ty ;
    return e ;
}

expty  transExp(S_table venv , S_table tenv , A_exp exp  , Tr_level level )  // done  «Œ™¡ÀºÏ≤‚break «∑Ò‘⁄’˝»∑µƒŒª÷√
{
    static bool done  = false ;
  if (exp == NULL )
  {
      assert(0);
  }
   switch(exp->kind)
   {
   case  A_varExp :
           return transVar(venv , tenv , exp->u.var , level ) ;
   case  A_nilExp :
          return expTy( Tr_nilExp() ,Ty_Nil());
   case  A_intExp :  // ’‚¿Ôµƒint «Àµµƒ’˚–Õ≥£¡ø ∂¯≤ª «int¿‡–Õ
          return expTy( Tr_intExp(exp->u.intt) , Ty_Int()) ;
   case  A_stringExp ://’‚¿Ôµƒstring  «Àµµƒ◊÷∑˚¥Æ≥£¡ø ∂¯≤ª «string¿‡–Õ
          return expTy( Tr_stringExp(exp->u.stringg) , Ty_String()) ;
   case  A_callExp :
          {
              E_enventry tmp = (E_enventry)S_look(venv, exp->u.call.func) ;
              if (tmp == NULL)
              {
                  assert(0) ;
              }
              Ty_tyList tylist  = tmp->u.fun.formals ;
              A_expList explist = exp->u.call.args ;
              Tr_expList trexplist = NULL ;
              while (tylist != NULL && explist != NULL)
              {
                  expty exptyp = transExp(venv , tenv , explist->head , level) ;
                 
                  if (exptyp.ty->kind == Ty_ty_::Ty_nil)
                  {
                      continue ;
                  }
                   if (!isTyequTy(tylist->head , exptyp.ty))
                   {
                       assert(0) ;
                   }
                    trexplist = Tr_ExpList(exptyp.exp , trexplist) ;
                  tylist = tylist->tail ;  explist = explist->tail ;
              }
              if (tylist != NULL || explist != NULL )
              {
                  assert(0);
              }

              return expTy(Tr_callExp(tmp->u.fun.label , tmp->u.fun.level , level , trexplist) , actrulyTy(tmp->u.fun.result)) ; 
          }
   case  A_opExp :
          {
              expty tmpleft = transExp(venv , tenv, exp->u.op.left , level ) ;
              expty tmpright = transExp(venv , tenv, exp->u.op.right , level ) ;
              switch(exp->u.op.oper)
              {
              case A_plusOp   : 
              case A_minusOp  : 
              case A_timesOp  : 
              case A_divideOp : 
                  {

                      if (tmpleft.ty->kind != Ty_ty_::Ty_int)
                          assert(0);
                      if (tmpright.ty->kind != Ty_ty_::Ty_int)
                          assert(0);   
                       return expTy(Tr_binopExp(tmpleft.exp , tmpright.exp ,exp->u.op.oper) , Ty_Int()) ; 
                  }
              case A_ltOp     : 
              case A_leOp     : 
              case A_gtOp     : 
              case A_geOp     : 
                     {
                         if (tmpleft.ty->kind != Ty_ty_::Ty_int)
                             assert(0);
                         if (tmpright.ty->kind != Ty_ty_::Ty_int)
                             assert(0);   
                         return expTy(Tr_relopExp(tmpleft.exp , tmpright.exp , exp->u.op.oper) , Ty_Int()) ;
                     }
              case A_eqOp :
              case A_neqOp: 
                     {
                         if (tmpleft.ty->kind == Ty_ty_::Ty_int
                             && tmpright.ty->kind == Ty_ty_::Ty_int)
                             return expTy(Tr_relopExp(tmpleft.exp , tmpright.exp , exp->u.op.oper)  , Ty_Int()) ;
                         if (tmpleft.ty->kind == tmpright.ty->kind)
                         {
                             if (tmpleft.ty->kind == Ty_ty_::Ty_record || tmpleft.ty->kind == Ty_ty_::Ty_array)
                             {
                                 if ( tmpleft.ty == tmpright.ty )
                                 {
                                     return expTy(Tr_relopExp(tmpleft.exp , tmpright.exp , exp->u.op.oper) , Ty_Int()) ;
                                 }
                             }
                         }
                         assert(0);
                     }
              }
              assert(0);
          }
   case  A_recordExp :
          {
              Ty_ty tmpty = (Ty_ty)S_look(tenv , exp->u.record.typ) ;
               tmpty = actrulyTy(tmpty) ;
               if (tmpty == NULL )
               {
                   assert(0) ;
               }
              if (tmpty->kind != Ty_ty_::Ty_record )
              {
                  assert(0) ;
              }
              A_efieldList tmpefield = exp->u.record.fields ;
              Ty_fieldList tmpfieldlist = tmpty->u.record ;
              Tr_expList trexplist = NULL ;
              int num = 0 ;
              while(tmpefield && tmpfieldlist)
              {    
                   expty tmp = transExp(venv , tenv , tmpefield->head->exp , level) ;
                  if (tmpefield->head->name != tmpfieldlist->head->name )
                  {
                      assert(0) ;
                  }
                  if (!isTyequTy(tmp.ty ,tmpfieldlist->head->ty))
                  {
                      assert(0) ;
                  }
                  trexplist = Tr_ExpList(tmp.exp , trexplist) ;
                  tmpefield = tmpefield->tail ; tmpfieldlist = tmpfieldlist->tail ; 
                  num ++;
              }
              if (tmpfieldlist!= NULL || tmpefield != NULL )
              {
                  assert(0) ;
              }
              expty tmp = expTy(Tr_recordExp(trexplist,num),tmpty));
Tr_FreeExplist(trexplist) ; // 只释放链表结构 不释放内容(hand)
return tmp ; } case A_seqExp : { A_expList explist = exp->u.seq ; Tr_expList trexplist = NULL ; if (explist) { while(explist->tail) { trexplist = Tr_ExpList(transExp( venv , tenv , explist->head , level).exp , trexplist) ; explist = explist->tail ; } } else { return expTy( Tr_seqExp(trexplist) , Ty_Void()); } expty tmp = transExp(venv , tenv , explist->head , level) ; trexplist = Tr_ExpList(tmp.exp , trexplist) ;
Tr_FreeExplist(trexplist) ; //只释放链表结构 不是放内容(hand)
return expTy(Tr_seqExp(trexplist) , tmp.ty); } case A_assignExp : { expty tmpV = transVar(venv , tenv , exp->u.assign.var , level) ; expty tmpE = transExp(venv , tenv , exp->u.assign.exp , level); if (tmpE.ty->kind != tmpV.ty->kind) { assert(0); } return expTy(Tr_assignExp(tmpV .exp , tmpE.exp) , Ty_Void()); } case A_ifExp : { expty tmptest = transExp(venv ,tenv , exp->u.iff.test , level) ; if(tmptest.ty->kind != Ty_ty_::Ty_int) { assert(0); } expty tmpthen = transExp(venv , tenv , exp->u.iff.then , level ) ; if (exp->u.iff.elsee != NULL) { expty tmpelse = transExp(venv , tenv , exp->u.iff.elsee , level) ; if ( tmpthen.ty != tmpelse.ty ) { assert(0); } return expTy( Tr_ifExp(tmptest.exp , tmpthen.exp , tmpelse.exp) , tmpelse.ty); } if (tmpthen.ty->kind != Ty_ty_::Ty_void) { assert(0); } return expTy(Tr_ifExp(tmptest.exp , tmpthen.exp , NULL) , Ty_Void()); } case A_whileExp : { expty test = transExp(venv , tenv , exp->u.whilee.test , level ); if (test.ty->kind != Ty_ty_::Ty_int) { assert(0) ; } expty body = transExp(venv , tenv , exp->u.whilee.body , level ); if ( done ) { // Àµ√˜’‚¿Ô√Ê”–break done = false ; } /* if (body.ty->kind != Ty_ty_::Ty_void) { assert(0); }*/ return expTy(Tr_whileExp(test.exp , body.exp , false) , Ty_Void()); } case A_forExp : { expty tmplo = transExp(venv , tenv , exp->u.forr.lo , level ); expty tmphi = transExp(venv , tenv , exp->u.forr.hi ,level ); S_beginScope(venv); Tr_access acc; acc = Tr_allocLocal(level , exp->u.forr.escape); // forŒ™ ≤√¥“™”–Ô“›£ø£ø£ø£ø£ø S_enter(venv , exp->u.forr.var , E_VarEntry( acc ,Ty_Int())); expty tmpbody = transExp(venv , tenv, exp->u.forr.body , level); if (tmplo.ty->kind != Ty_ty_::Ty_int || tmphi.ty->kind != Ty_ty_::Ty_int ) { assert(0); } S_endScope(venv); return expTy(Tr_forExp(acc, tmphi.exp , tmplo.exp , tmpbody.exp) , Ty_Void()); } case A_breakExp : { done = true ; return expTy(Tr_breakExp() , Ty_Void()); } case A_letExp : { S_beginScope(venv); S_beginScope(tenv); A_decList declist = exp->u.let.decs ; Tr_expList trexplist = NULL ; while(declist != NULL) { trexplist = Tr_ExpList(transDec(venv , tenv , declist->head , level) , trexplist) ; declist = declist->tail; } expty tmp ; if (exp->u.let.body) { tmp = transExp(venv , tenv , exp->u.let.body , level); tmp = expTy(Tr_letExp(trexplist , tmp.exp) , tmp.ty) ; } else { tmp = expTy(Tr_letExp(trexplist , NULL) , Ty_Void()) ; }
Tr_FreeExplist(trexplist) ;//只释放链表结构,不是放链表内容(hand) S_endScope(venv); S_endScope(tenv);
return tmp ; } case A_arrayExp : { Ty_ty ty = (Ty_ty)S_look(tenv , exp->u.array.typ); ty = actrulyTy(ty); if (ty == NULL || ty->kind != Ty_ty_::Ty_array) { assert(0); } expty tynum = transExp(venv , tenv , exp->u.array.size , level ); if (tynum.ty->kind != Ty_ty_::Ty_int) { assert(0); } expty tyinit = transExp(venv , tenv, exp->u.array.init , level ) ; if (tyinit.ty != ty->u.array ) { assert(0) ; } return expTy(Tr_arryExp(tynum.exp, tyinit.exp) , ty); } } assert(0); } expty transVar(S_table venv , S_table tenv , A_var var , Tr_level level) { switch(var->kind) { case A_simpleVar : { E_enventry tmp = (E_enventry) S_look(venv , var->u.simple) ; if (tmp != NULL && tmp->kind == E_enventry_::E_varEntry) { return expTy(Tr_simpleVar(tmp->u.var.access , level), actrulyTy(tmp->u.var.ty)) ; } assert(0) ; } case A_fieldVar : { expty tmpty = transVar(venv , tenv , var->u.field.var , level) ; if (tmpty.ty->kind != Ty_ty_::Ty_record) { assert(0); } Ty_fieldList fieldList = tmpty.ty->u.record ; int num = 0; while( fieldList ) { if ( fieldList->head->name == var->u.field.sym ) { return expTy(Tr_fieldVar(tmpty.exp ,num) , actrulyTy(fieldList->head->ty)) ; } num ++ ; fieldList = fieldList->tail ; } assert(0); } case A_subscriptVar : { expty tmp = transVar(venv , tenv , var->u.subscript.var , level) ; if (tmp.ty->kind != Ty_ty_::Ty_array ) { assert(0) ; } expty tmpexp = transExp(venv , tenv , var->u.subscript.exp , level ) ; if (tmpexp.ty->kind != Ty_ty_::Ty_int) { assert(0) ; } return expTy(Tr_subscriptVar(tmp.exp ,tmpexp.exp) , tmp.ty) ; } } assert(0) ; } Tr_exp transDec(S_table venv , S_table tenv , A_dec dec , Tr_level level) { switch(dec->kind) { case A_functionDec : { A_fundecList tmpfun = dec->u.function ; Tr_level newlevel ; Tr_access acce ; U_boolList boollist = NULL ; Ty_ty reslut = NULL ; while(tmpfun) { A_fieldList tmpfeldList = tmpfun->head->params ; Ty_tyList tylist = NULL ; while(tmpfeldList) { Ty_ty ty = (Ty_ty)S_look(tenv,tmpfeldList->head->typ); if (ty == NULL ) { assert(0) ; } tylist = Ty_TyList(ty , tylist) ; tmpfeldList = tmpfeldList->tail ; boollist = U_BoolList(true , boollist) ; } if (innerIdentifiers(tmpfun->head->name)) { assert(0) ; } //¿‡À∆”⁄…˘√˜“ª∏ˆ∫Ø ˝ ªπ√ª”–∂®“ÂÀ¸ newlevel = Tr_newLevel(level ,Temp_newlabel() ,boollist); reslut = (Ty_ty)S_look(tenv ,tmpfun->head->result) ; if (reslut == NULL ) { reslut = Ty_Void() ; } S_enter(venv , tmpfun->head->name , E_FunEntry( newlevel, newlevel->frame->name , tylist , reslut)) ; tmpfun = tmpfun->tail ; U_ClearBoolList(boollist) ; // “ÚŒ™÷ª «”√¡Àbool ≤¢√ª”–±£¥ÊÀ¸ À˘“‘ªπ“™ Õ∑≈“ªœ¬ boollist = NULL ; } tmpfun = dec->u.function ; E_enventry funEntry; Tr_accesslist tr_acceselist , tmpacclist ; Tr_expList trexplist = NULL ; while(tmpfun) { S_beginScope(venv) ; funEntry = (E_enventry) S_look(venv , tmpfun->head->name) ; tmpacclist = tr_acceselist = Tr_formals(funEntry->u.fun.level) ; A_fieldList tmpfeldList = tmpfun->head->params ; // ’‚¿Ô“™øº¬«µΩparamsµƒ…˙≥…∑Ω Ω »Áπ˚∫Õtr_accesslist≤ª“ª÷¬“™∏ƒ“ªœ¬ while(tmpfeldList) { Ty_ty ty = (Ty_ty)S_look(tenv,tmpfeldList->head->typ); if (innerIdentifiers(tmpfeldList->head->name)) { assert(0); } S_enter(venv ,tmpfeldList->head->name, E_VarEntry(tmpacclist->head,ty)) ; tmpfeldList = tmpfeldList->tail ; tmpacclist = tmpacclist->tial ; } expty tmp = transExp(venv , tenv , tmpfun->head->body , newlevel) ; trexplist = Tr_ExpList(tmp.exp , trexplist) ; if (tmp.ty != actrulyTy(funEntry->u.fun.result)) { assert(0) ; } Tr_ClearAcces(tr_acceselist) ; //÷ª π”√¡Àhead tail≤ø∑÷«Â¿Ì∏…æª S_endScope(venv) ; tmpfun = tmpfun->tail ; } return Tr_funDec(trexplist) ; } case A_typeDec : { A_nametyList namelist = dec->u.type ; while(namelist) { if (innerIdentifiers(namelist->head->name)) { assert(0) ; } // ¥¶¿Ìµ›πÈ ¿‡À∆”⁄ …˘√˜“ª∏ˆ¿‡–Õ µ´ «ªπ√ª”–∂®“ÂÀ¸ S_enter(tenv , namelist->head->name ,Ty_Name(namelist->head->name , NULL)) ; namelist = namelist->tail ; } namelist = dec->u.type ; while(namelist) { // ¥¶¿Ìµ›πÈ Ty_ty tmp1 = transTy(tenv , namelist->head->ty ) ; Ty_ty tmp2 = (Ty_ty)S_look(tenv , namelist->head->name) ; if ( tmp1->kind == Ty_ty_::Ty_int || tmp1->kind == Ty_ty_::Ty_string || tmp1->kind == Ty_ty_::Ty_nil || tmp1->kind == Ty_ty_::Ty_void) { //ƒ⁄÷√¿‡–Õ π”√µƒ «Õ¨“ª«¯”Úƒ⁄¥Ê Œ™¡À±£≥÷ø…“‘æ≠––÷∏’僱»ΩœæÕ÷±Ω”»∑∂® «∑ÒŒ™Õ¨“ª∏ˆ¿‡–Õ ƒ«√¥æÕ“™÷±Ω”∞—∞Û∂®∏¯ªª¡À tmp2 = (Ty_ty)S_changeBind(tenv , namelist->head->name , tmp1); tmp2 = (Ty_ty)freeTy(tmp2) ; } else { //»Áπ˚≤ª «’‚Àƒ÷÷ƒ⁄÷√¿‡–Õ “™œ˙ªŸ tyCpy(tmp2 , tmp1) ; tmp1 = (Ty_ty)freeTy(tmp1) ; } namelist = namelist->tail ; } namelist = dec->u.type; while(namelist) { // ¥¶¿Ì —≠ª∑µ›πÈ ¿˝»Á type a = b type b = a Ty_ty tmp = (Ty_ty)S_look(tenv , namelist->head->name) ; if (!actrulyTy(tmp)) { assert(0) ; } namelist = namelist->tail ; } return Tr_typeDec(); } case A_varDec : { if(dec->u.var.init == NULL) { assert(0) ; } expty tmp = transExp(venv , tenv , dec->u.var.init , level ) ; if( (dec->u.var.typ != NULL) ) { if ( actrulyTy((Ty_ty)S_look(tenv ,dec->u.var.typ)) != tmp.ty) { assert(0) ; } } if (innerIdentifiers(dec->u.var.var)) { assert(0) ; } Tr_access acc = Tr_allocLocal(level , dec->u.var.escape) ; S_enter(venv , dec->u.var.var ,E_VarEntry( acc ,tmp.ty)) ; return Tr_varDec(acc , tmp.exp); } } assert(0) ; } Ty_ty transTy(S_table tenv , A_ty ty) { switch(ty->kind) { case A_nameTy : { if (S_Symbol("int") == ty->u.name) { return Ty_Int(); } if (S_Symbol("string") == ty->u.name) { return Ty_String(); } Ty_ty tmp = (Ty_ty)S_look(tenv , ty->u.name) ; if ( tmp == NULL ) { assert(0) ; } return Ty_Name(ty->u.name , tmp) ; } case A_recordTy : { A_fieldList tmpfeldList = ty->u.record ; Ty_fieldList tyfdlist = NULL ; while(tmpfeldList) { Ty_ty tmp = (Ty_ty)S_look(tenv , tmpfeldList->head->typ) ; if ( tmp == NULL ) { assert(0) ; } if (innerIdentifiers(tmpfeldList->head->name)) { assert(0); } tyfdlist = Ty_FieldList(Ty_Field( tmpfeldList->head->name , tmp) , tyfdlist) ; tmpfeldList = tmpfeldList->tail ; } return Ty_Record(tyfdlist); } case A_arrayTy : { Ty_ty tmp = (Ty_ty)S_look(tenv , ty->u.array); if ( tmp == NULL ) { assert(0); } return Ty_Array(tmp) ; } } assert(0) ; } bool innerIdentifiers( S_symbol sym) { if (sym == S_Symbol("int") || sym == S_Symbol("string") ) { return true ; } return false ; }

 

转载于:https://www.cnblogs.com/BlackWalnut/p/4559717.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
作者简介: Andrew W.Appel,美国普林斯顿大学计算机科学系教授,第26届ACM SIGPLAN-SIGACT程序设计原理年会大会执行主席,1998-1999年在贝尔实验室做研究工作。主要研究方向是计算机安全、编译器设计、程序设计语言等。 内容简介: 本书全面讲述了现代编译器的各个组成部分,包括词法分析、语法分析、抽象语法、语义检查、中间代码表示、指令选择、数据流分析、寄存器分配以及运行时系统等。全书分成两部分,第一部分是编译的基础知识,适用于第一门编译原理课程(一个学期);第二部分是高级主题,包括面向对象语言和函数语言、垃圾收集、循环优化、SSA(静态单赋值)形式、循环调度、存储结构优化等,适合于后续课程或研究生教学。书中专门为学生提供了一个用C语言编写的实习项目,包括前端和后端设计,学生可以在一学期内创建一个功能完整的编译器。   本书适用于高等院校计算机及相关专业的本科生或研究生,也可供科研人员或工程技术人员参考。 目录: 第一部分 编译基本原理 第1章 绪论 1 1.1 模块与接口 1 1.2 工具和软件 3 1.3 语言的数据结构 3 程序设计:直线式程序解释器 7 推荐阅读 9 习题 9 第2章 词法分析 10 2.1 词法单词 10 2.2 正则表达式 11 2.3 有限自动机 13 2.4 非确定有限自动机 15 2.4.1 将正则表达式转换为NFA 16 2.4.2 将NFA转换为DFA 18 2.5 Lex:词法分析器的生成器 20 程序设计:词法分析 22 推荐阅读 23 习题 23 第3章 语法分析 27 3.1 上下文无关文法 28 3.1.1 推导 29 3.1.2 语法分析 29 3.1.3 二义性文法 30 3.1.4 文件结束符 31 3.2 预测分析 32 3.2.1 FIRST集合和FOLLOW集合 33 3.2.2 构造一个预测分析器 35 3.2.3 消除左递归 36 3.2.4 提取左因子 37 3.2.5 错误恢复 37 3.3 LR分析 39 3.3.1 LR分析引擎 40 3.3.2 LR(0)分析器生成器 41 3.3.3 SLR分析器的生成 44 3.3.4 LR(1)项和LR(1)分析表 45 3.3.5 LALR(1)分析表 46 3.3.6 各类文法的层次 47 3.3.7 二义性文法的LR分析 47 3.4 使用分析器的生成器 48 3.4.1 冲突 49 3.4.2 优先级指导 50 3.4.3 语法和语义 53 3.5 错误恢复 54 3.5.1 用error符号恢复 54 3.5.2 全局错误修复 55 程序设计:语法分析 57 推荐阅读 58 习题 58 第4章 抽象语法 62 4.1 语义动作 62 4.1.1 递归下降 62 4.1.2 Yacc生成的分析器 62 4.1.3 语义动作的解释器 64 4.2 抽象语法分析 65 4.2.1 位置 67 4.2.2 Tiger的抽象语法 68 程序设计:抽象语法 71 推荐阅读 71 习题 72 第5章 语义分析 73 5.1 符号表 73 5.1.1 多个符号表 74 5.1.2 高效的命令式风格符号表 75 5.1.3 高效的函数式符号表 76 5.1.4 Tiger编译器的符号 77 5.1.5 函数式风格的符号表 79 5.2 Tiger编译器的绑定 79 5.3 表达式的类型检查 82 5.4 声明的类型检查 84 5.4.1 变量声明 84 5.4.2 类型声明 85 5.4.3 函数声明 85 5.4.4 递归声明 86 程序设计:类型检查 87 习题 87 第6章 活动记录 89 6.1 栈帧 90 6.1.1 帧指针 91 6.1.2 寄存器 92 6.1.3 参数传递 92 6.1.4 返回地址 94 6.1.5 栈帧内的变量 94 6.1.6 静态链 95 6.2 Tiger编译器的栈帧 96 6.2.1 栈帧描述的表示 98 6.2.2 局部变量 98 6.2.3 计算逃逸变量 99 6.2.4 临时变量和标号 100 6.2.5 两层抽象 100 6.2.6 管理静态链 102 6.2.7 追踪层次信息 102 程序设计:栈帧 103 推荐阅读 103 习题 103 第7章 翻译成中间代码 106 7.1 中间表示 106 7.2 翻译为中间语言 108 7.2.1 表达式的种类 108 7.2.2 简单变量 111 7.2.3 追随静态链 112 7.2.4 数组变量 113 7.2.5 结构化的左值 114 7.2.6 下标和域选择 114 7.2.7 关于安全性的劝告 115 7.2.8 算术操作 116 7.2.9 条件表达式 1
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值