现代编译原理--第六章(中间树 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();
} 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();
}
#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();
}
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(), 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();
}
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()),
T_Eseq( exp->u.cx.stm ,
T_Eseq( T_Label(f) ,
T_Eseq(T_Move(T_Temp(tmp) , T_Const()) ,
T_Eseq(T_Label(t) ,
T_Temp(tmp)))))) ; }
case GetExpNx :
{
return T_Eseq(exp->u.nx, T_Const());// Œ™ ≤√¥“™∑µªÿ0 ’‚∏ˆnx≤ª «Œfi÷µ”Ôæ‰√¥
}
}
assert();
} 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(), 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 - )*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 - ) * 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())) , 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()) ;
} 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();
}
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() ;
}
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() ;
}
trexplist = Tr_ExpList(exptyp.exp , trexplist) ;
tylist = tylist->tail ; explist = explist->tail ;
}
if (tylist != NULL || explist != NULL )
{
assert();
} 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();
if (tmpright.ty->kind != Ty_ty_::Ty_int)
assert();
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();
if (tmpright.ty->kind != Ty_ty_::Ty_int)
assert();
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();
}
}
assert();
}
case A_recordExp :
{
Ty_ty tmpty = (Ty_ty)S_look(tenv , exp->u.record.typ) ;
tmpty = actrulyTy(tmpty) ;
if (tmpty == NULL )
{
assert() ;
}
if (tmpty->kind != Ty_ty_::Ty_record )
{
assert() ;
}
A_efieldList tmpefield = exp->u.record.fields ;
Ty_fieldList tmpfieldlist = tmpty->u.record ;
Tr_expList trexplist = NULL ;
int num = ;
while(tmpefield && tmpfieldlist)
{
expty tmp = transExp(venv , tenv , tmpefield->head->exp , level) ;
if (tmpefield->head->name != tmpfieldlist->head->name )
{
assert() ;
}
if (!isTyequTy(tmp.ty ,tmpfieldlist->head->ty))
{
assert() ;
}
trexplist = Tr_ExpList(tmp.exp , trexplist) ;
tmpefield = tmpefield->tail ; tmpfieldlist = tmpfieldlist->tail ;
num ++;
}
if (tmpfieldlist!= NULL || tmpefield != NULL )
{
assert() ;
}
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();
}
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();
}
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();
}
return expTy( Tr_ifExp(tmptest.exp , tmpthen.exp , tmpelse.exp) , tmpelse.ty);
}
if (tmpthen.ty->kind != Ty_ty_::Ty_void)
{
assert();
}
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() ;
}
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();
}
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();
}
expty tynum = transExp(venv , tenv , exp->u.array.size , level );
if (tynum.ty->kind != Ty_ty_::Ty_int)
{
assert();
}
expty tyinit = transExp(venv , tenv, exp->u.array.init , level ) ;
if (tyinit.ty != ty->u.array )
{
assert() ;
}
return expTy(Tr_arryExp(tynum.exp, tyinit.exp) , ty);
}
}
assert();
} 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() ;
}
case A_fieldVar :
{
expty tmpty = transVar(venv , tenv , var->u.field.var , level) ;
if (tmpty.ty->kind != Ty_ty_::Ty_record)
{
assert();
}
Ty_fieldList fieldList = tmpty.ty->u.record ;
int num = ;
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();
}
case A_subscriptVar :
{
expty tmp = transVar(venv , tenv , var->u.subscript.var , level) ;
if (tmp.ty->kind != Ty_ty_::Ty_array )
{
assert() ;
}
expty tmpexp = transExp(venv , tenv , var->u.subscript.exp , level ) ;
if (tmpexp.ty->kind != Ty_ty_::Ty_int)
{
assert() ;
}
return expTy(Tr_subscriptVar(tmp.exp ,tmpexp.exp) , tmp.ty) ;
}
}
assert() ;
} 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() ;
}
tylist = Ty_TyList(ty , tylist) ;
tmpfeldList = tmpfeldList->tail ;
boollist = U_BoolList(true , boollist) ;
}
if (innerIdentifiers(tmpfun->head->name))
{
assert() ;
}
//¿‡À∆”⁄…˘√˜“ª∏ˆ∫Ø ˝ ªπ√ª”–∂®“ÂÀ¸
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();
}
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() ;
}
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() ;
}
// ¥¶¿Ìµ›πÈ ¿‡À∆”⁄ …˘√˜“ª∏ˆ¿‡–Õ µ´ «ªπ√ª”–∂®“ÂÀ¸
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() ;
}
namelist = namelist->tail ;
}
return Tr_typeDec();
}
case A_varDec :
{
if(dec->u.var.init == NULL)
{
assert() ;
}
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() ;
}
}
if (innerIdentifiers(dec->u.var.var))
{
assert() ;
}
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() ;
} 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() ;
}
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() ;
}
if (innerIdentifiers(tmpfeldList->head->name))
{
assert();
}
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();
}
return Ty_Array(tmp) ;
}
}
assert() ;
} bool innerIdentifiers( S_symbol sym)
{
if (sym == S_Symbol("int") || sym == S_Symbol("string") )
{
return true ;
}
return false ;
}
现代编译原理--第六章(中间树 IR Tree 含源码)的更多相关文章
- 现代编译原理——第六章:中间树 IR Tree 含源码
转自: http://www.cnblogs.com/BlackWalnut/p/4559717.html 这一章,就虎书而言,理论知识点是及其少的,就介绍了为什么要有一个中间表示树.看下面这张图就能 ...
- 编译哈工大语言技术平台云LTP(C++)源码及LTP4J(Java)源码
转自:编译哈工大语言技术平台云LTP(C++)源码及LTP4J(Java)源码 JDK:java version “1.8.0_31”Java(TM) SE Runtime Environment ( ...
- java集合树状结构及源码
java集合树状结构及源码 最近一直想看一下java集合的源码,毕竟平时用的比较多,但总是感觉是跟着习惯new出来一个对象,比如ArrayList,HashMap等等,所以就简单的看了一下,了解了一下 ...
- 编译原理(六)自底向上分析之LR分析法
自底向上分析之LR分析法 说明:以老师PPT为标准,借鉴部分教材内容,AlvinZH学习笔记. 基本概念 1. LR分析:从左到右扫描(L)自底向上进行规约(R),是规范规约,也即最右推导(规范推导) ...
- 第三十六节,目标检测之yolo源码解析
在一个月前,我就已经介绍了yolo目标检测的原理,后来也把tensorflow实现代码仔细看了一遍.但是由于这个暑假事情比较大,就一直搁浅了下来,趁今天有时间,就把源码解析一下.关于yolo目标检测的 ...
- [Unity插件]Lua行为树(一):BehaviorDesigner源码分析
BehaviorDesigner是Unity上的一款行为树插件,不过这个插件是用C#编写的,编写出来的行为树也是依赖于C#的,不利于热更,所以有必要写一个lua版本的. 首先下载BehaviorDes ...
- 含源码解析,深入Java 线程池原理
从池化技术到底层实现,一篇文章带你贯通线程池技术. 1.池化技术简介 在系统开发过程中,我们经常会用到池化技术来减少系统消耗,提升系统性能. 在编程领域,比较典型的池化技术有: 线程池.连接池.内存池 ...
- ElasticStack系列之十六 & ElasticSearch5.x index/create 和 update 源码分析
开篇 在ElasticSearch 系列十四中提到的问题即 ElasticStack系列之十四 & ElasticSearch5.x bulk update 中重复 id 性能骤降,继续这个问 ...
- 单独编译和使用webrtc音频回声消除模块(附完整源码+测试音频文件)
单独编译和使用webrtc音频降噪模块(附完整源码+测试音频文件) 单独编译和使用webrtc音频增益模块(附完整源码+测试音频文件) 说实话很不想写这篇文章,因为这和我一贯推崇的最好全部编译并使用w ...
随机推荐
- Python 算术运算符
Python 算术运算符 运算结果为浮点数 除法:/ 整除: // 求余计算: % 求余运算可以用于固定时间的检测,比如说每10分钟进行一次什么样的操作,则:minute % 10 乘方运算:
- eclipse各版本及下载
附:Eclipse各个版本简介(http://zh.wikipedia.org/wiki/Eclipse) eclipse下载地址: https://www.eclipse.org/官网--右上角的I ...
- note 0 Python介绍及Python IDE环境安装 Spyder with Anaconda
高级语言分类 编译型语言(C/C++等) 解释型语言(BASIC.Python等) Python 诞生于1989年,创始人为吉多 范罗苏姆(Guido van Rossum) Python 语言特点 ...
- 部署MySQL自动化运维工具inception+archer
***************************************************************************部署MySQL自动化运维工具inception+a ...
- MySQL导出数据字典
平时用mysql比较多,有时候需要详细的数据库设计表结构和数据字典,但又没有最新的文档,这个时候直接从数据导出是最新最全的.在MySQL数据库中利用information_schema库中的COLUM ...
- 将打印(printk/printf)及时写入文件的方法
问题是这样的,在测试一个gps的app的时候,我使用脚本 “ gps_test_app > /tmp/gps_log.txt &" 但是但是,去查看gps_log.txt的 ...
- ADB server didn't ACK failed to start daemon 5037
错误信息: C:\Users\lizy>adb devices adb devicesadb server is out of date. killing... ADB server didn ...
- 网页提示504 gateway time-out是什么意思?如何解决?
大家在访问网站的时候通常会遇到502错误.404错误等,很少会遇到504错误.但是在我们去访问大流量或者内容数据量较多的网站时,打开网页偶尔就会出现504 gateway time-out,这到底是什 ...
- solr字段压缩属性compressed新版本已经移除
solr字段压缩属性compressed新版本已经移除 可能是考虑到压缩意义不大还减少搜索效率,所以去掉了.而且好像没有替代属性.
- Variables多种表达
Variables:TF基础数据之一,常用于变量的训练...重要性刚学TF就知道了 1.tf.Variable() tf.Variable(initial_value=None, trainable= ...