tiger语义分析(类型判断)- 完整版

本文介绍了Tiger语言的语义分析和类型判断的实现,包括`Semant.c`中定义的环境处理,`env.c`中的变量和函数环境构建,以及`Set.c`中的集合操作。通过`parse.c`中的解析和测试代码展示了如何处理源文件并进行抽象语法树的构建和类型检查。
摘要由CSDN通过智能技术生成

引用:https://blog.csdn.net/lhfl911/article/details/61206047

在编写后,与引用处的代码进行对比参考过,借鉴了一些地方,并进行了完善。

实现包含:

1、使用地址进行比较(地址隐含了名称符号信息),比较两个类型名是否相同。
2、使用Set。递归序列中,对重复类型声明、重复函数声明的检测(重复变量声明是允许的,非递归序列下,重复类型和函数也是允许的)。函数参数声明中对相同参数名的检测。结构声明中对相同成员名的检测。
3、在E_enventry中添加变量是否能被赋值标志,对for语句循环控制量的不正确赋值进行检测。
4、更小的作用域变量可以覆盖更大作用域的相同变量名的变量声明,这是合法的。例子见test37.tig。
完成对testcases里所有的例程进行解析。如有未发现的错误,敬请指正。

Semant.c”的代码如下:

=========================================================================

#include "util.h"

#include "symbol.h" /* symbol table data structures */
#include "absyn.h"  /* abstract syntax data structures */
#include "types.h"
#include "env.h"
#include "errormsg.h"
#include "Semant.h"
#include <string.h>
#include "set.h"


unsigned char break_enable =0;


//值传递的方式
struct expty expTy(Tr_exp exp, Ty_ty ty){
  struct expty e;e.exp = exp; e.ty = ty;return e;
}


struct expty transExp(S_table v_env, S_table t_env, A_exp exp);


Ty_ty actual_ty(Ty_ty ty){
  Ty_ty t = ty;
  
  while(ty&&(ty->kind == Ty_name)){
ty = ty->u.name.ty;
assert(ty!=t);
  }
  return ty;
}


int ty_compare(Ty_ty ty1, Ty_ty ty2){
Ty_ty t1 = actual_ty(ty1);
Ty_ty t2 = actual_ty(ty2);
return ( ((t1->kind == t2->kind)&&(t1->kind != Ty_record)&&(t1->kind != Ty_array))\
||( ( (t1->kind == Ty_nil)&&(t2->kind ==Ty_record) )||((t1->kind == Ty_record)&&(t2->kind == Ty_nil) ))
||(t1 == t2));
}
   
Ty_ty transField(S_table v_env, S_table t_env, Ty_fieldList record, S_symbol sym){
  for(;record;record=record->tail){
  if(record->head->name == sym){
break;
}
  }
  if(record) return record->head->ty;
  else return NULL;
}


struct expty transVar(S_table v_env, S_table t_env, A_var var){
  assert(var);
  switch(var->kind){
  case A_simpleVar:{
E_enventry e  = S_look(v_env, var->u.simple);
if(e && (e->kind == E_varEntry)){
 return expTy(NULL,actual_ty(e->u.var.ty));
}
else {
 EM_error(var->pos, "undefined variable %s", S_name(var->u.simple));
}
return expTy(NULL,Ty_Int());
  }
  case A_fieldVar:{
struct expty t1 = transVar(v_env,t_env,var->u.field.var);
if(t1.ty->kind != Ty_record){
 EM_error(var->u.field.var->pos, "need a record type.");
}
else {
 Ty_ty ty1 = transField(v_env, t_env, t1.ty->u.record, var->u.field.sym);
 if(ty1){
return expTy(NULL,actual_ty(ty1));
 }
 else {
EM_error(var->pos, "undefined field %s", S_name(var->u.field.sym));
 }
}
return expTy(NULL,Ty_Int());
  }
  case A_subscriptVar:{
struct expty t1 = transVar(v_env,t_env,var->u.subscript.var);
if(t1.ty->kind != Ty_array){
  EM_error(var->u.subscript.var->pos, "need a array type.");
}
else {
 struct expty t2 = transExp(v_env, t_env, var->u.subscript.exp);
 if(t2.ty->kind != Ty_int)  EM_error(var->u.subscript.exp->pos, "need int val.");
 return expTy(NULL, t1.ty->u.array);
}
return expTy(NULL,Ty_Int());
  }
  default:
assert(0);
  }
  
}


void transFormals(S_table v_env, S_table t_env, Ty_tyList tlist, A_exp exp){
  A_expList elist;
  assert(exp->kind == A_callExp);
  elist = exp->u.call.args;
  //tlist 和 elist 都有可能为空
  if((tlist ==NULL) ^ (elist ==NULL)){
EM_error(exp->pos, "%s Parameter num inconsistency.",S_name(exp->u.call.func));
return;
  }
  if(tlist == NULL)return;
  for(;tlist&&elist;tlist = tlist->tail, elist = elist->tail){

 struct expty t = transExp(v_env, t_env, elist->head);
 //t不会返回空
 if(!ty_compare(t.ty, tlist->head)){
EM_error(elist->head->pos, "Type inconsistency.");
 }
 
  }
   if((tlist !=NULL) || (elist !=NULL)){
EM_error(exp->pos, "%s Parameter num inconsistency.",S_name(exp->u.call.func));
return;
  }
  return;
  
}






void transEfields(S_table v_env, S_table t_env, Ty_fieldList tlist, A_efieldList slist){
  if(slist == NULL)return;
  for(;slist;slist = slist->tail){
Ty_ty t = transField(v_env, t_env, tlist, slist->head->name);
if(t){
 struct expty e = transExp(v_env, t_env, slist->head->exp);

 if (!ty_compare(e.ty, t)){
EM_error(slist->head->exp->pos, "Expression type inconsistency with %s.",S_name(slist->head->name));
 }
}
else {
 EM_error(slist->head->exp->pos, "undefined field %s", S_name(slist->head->name));
}
  }
}


Ty_tyList makeFormalTyList(S_table t_env, A_fieldList ls, Set s){
   
  if(ls){
//为保持跟之后参数变量调用时顺序一致,这里使用递归,并且设定从头的顺序排除后面重复名的变量
if(!Set_Push(s, ls->head->name)){
EM_error(ls->head->pos, "param name:%s is repeated.",S_name(ls->head->name));
return makeFormalTyList(t_env,ls->tail, s);
 }

Ty_tyList tylist = makeFormalTyList(t_env,ls->tail, s);
 
 
 Ty_ty t = S_look(t_env, ls->head->typ );
 if(!t){
EM_error(ls->head->pos, "Type %s undefined.",S_name(ls->head->typ));
t = Ty_Int();
 }
 
 tylist = Ty_TyList(t, tylist);
      return tylist;
  }
  else return NULL;
  


}


void transFunDecList(S_table v_env, S_table t_env, A_
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值