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

tiger 语义分析(类型检查) 为编译器实现类型检查。 在语法分析的基础上,对抽象语法树进行类型检查,并生成相关报错信息。完成语法分析的基础上,还需: types.[ch]: 已给出,描述了tiger语言的数据类型 env.[ch]: 实现值环境、类型环境 semant.[ch]:实现类型检查函数SEM_transProg(A_exp exp) semtest.c: 测试平台,main入口 修改makefi 阅读详情

引用:https://blog.youkuaiyun.com/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_fundecList flist){
  //先把所有相连的函数都录进去,因为可能递归
  Set global_set = Set_Empty();
  Set global_set2 = Set_Emp
7、语义分析:编译器的关键环节 本文深入探讨了编译器中语义分析这一关键环节,详细解析了符号表的作用及其管理方式,包括函数式与命令式实现风格的对比。同时,文章介绍了Tiger编译器中的类型系统、值环境、类型检查机制以及作用域管理策略,并讨论了符号表性能优化的方法。通过实际代码示例和流程图,帮助读者理解语义分析在编译过程中的具体应用与实现技巧。 阅读详情

相关推荐

10、Tiger编译器中的栈帧管理与优化

本文深入探讨了Tiger编译器中的栈帧管理与优化机制,涵盖了栈帧调用与访问机制、局部变量的存储与逃逸分析、静态链接与显示表的实现原理,以及与机器无关的抽象接口设计。通过详细解析栈帧在函数调用中的作用、变量存储位置的选择和优化策略,帮助读者理解如何高效地进行函数调用和变量访问。此外,文章还对比了静态链接与显示表的优劣,并提供了相关的编程练习与历史背景,为编译器设计与优化提供了全面的视角。

k8s6orchestrator的博客 72

8、类型检查与激活记录全解析

本文深入解析了编程语言中的类型检查机制与激活记录管理,详细阐述了类型环境与值环境的构建、表达式与声明的类型检查流程,以及递归声明的处理方式。同时,讨论了局部变量的生命周期管理,比较了栈与闭包在不同语言中的实现与应用,适用于对编译原理和编程语言实现感兴趣的开发者和研究人员。

k8s6orchestrator的博客 76

OCaml实现的Tiger编译器: 教学示例

编译器是程序设计的核心,它将人类可读的高级编程语言转换成机器语言。Tiger编译器是用于教学和研究目的的编译器,它实现了从Tiger语言到C语言的编译过程。Tiger语言是一个小型的教学语言,其设计兼顾了易学性和强大的表达能力,非常适合于编译原理的教学与实践。OCaml作为一种多范式的编程语言,其函数式编程的特性为编译器开发带来了诸多优势。首先,函数式编程鼓励使用不可变数据和纯粹的函数,这在编译器中是特别有价值的。

weixin_31641077的博客 583

Tiger语言编译器项目:编译原理的实践与探索

Tiger语言是一款为教学目的设计的编程语言,由Andrew Appel和David MacQueen在《现代编译原理:C语言描述》一书中提出。它提供了一套简洁的语法和编译器设计模型,使得学习编译原理变得更为直观。在编译器的设计与实现过程中,确立清晰的设计目标是至关重要的第一步。Tiger编译器的设计目标可以被概括为提供一个既高效又灵活的编译平台,以便于处理现代编程语言特性,同时保持对多样硬件平台的支持。

weixin_35516273的博客 736

OCamlTiger:用OCaml实现现代编译器的设计与实践

OCamlTiger 是一个开源项目,旨在通过 OCaml 语言实现 Tiger 编程语言的编译器。Tiger 编程语言是一种教学语言,因 Aho, Lam, Sethi 和 Ullman 的编译原理教科书而闻名。OCamlTiger 项目不仅为学习编译器设计提供了宝贵的实践机会,还为 OCaml 语言爱好者提供了一个展示编译器技术的平台。

weixin_42610671的博客 977

tiger:“ ML中的现代编译器实现”中的Tiger语言编译器

tiger:“ ML中的现代编译器实现”中的Tiger语言编译器

tiger-haskell:Haskell 中的现代编译器实现(Tiger 编程语言)

老虎哈斯克尔 Haskell 中的现代编译器实现(Tiger 编程语言) 这是一个尝试创建一个tiger编程语言编译器,因为我想在做一些有趣的事情的同时学习Haskell。 一年前,我参加了耶鲁 CPSC 421 课程,我们用 SML 为同一种语言实现了一个编译器。 那时我们有很多样板代码,但这次我会尝试从头开始制作所有内容。 我对 Haskell 很陌生,我可能会犯很多错误。 如果你发现任何不好的地方,请告诉我! 我将不胜感激! 如何使用它 git clone https://github.com/hengchu/tiger-haskell cd tiger-haskell cabal sandbox init cabal install --dependencies-only cabal build 现在的进展 编译器应该适用于此处列出的所有测试用例: : 我正在为这个 T

Tiger语言语法手册

tiger语言的语法手册,拿《Modern Compiler》做编译原理课程设计的必备哦~~~

tiger-types-osgi-2.1.93.zip

etp.zip,用于java的erlang术语分析器

tiger编译器(完整版包括编译报告)

由JAVA完成的tiger编译器 能够正确运行汇编程序 知道很多同学在痛苦,但是还是希望大家自己完成。代码只是作为参考。

Camera AF和FF

Camera按对焦功能可以分为FF(Fixed Focus)和AF(Auto Focus),即固定对焦和自动对焦。固定对焦顾名思义就是焦距是固定的,而自动对焦可以通过移动镜头位置来改变焦距从而实现自动对焦。以前摄像的功能机大多是固定对焦,现在的手机都带有自动对焦功能。 FF模组包括镜头(Lens),传感器(Sensor),红外滤色器(IR Filter),电路板(PCB),镜头支撑(Lens Holder),连接器(Connector)。 Fig 1. FF Module AF模组包括FF模组,音圈马达(V

Coppa的博客 1万+

游戏经济数值模型的搭建过程——以标准卡牌游戏为例

一、总体规划 1.玩家分类 首先我们按照下表对玩家进行分类 付费能力即为充值额度;充值行为比如购买月卡/购买钻石;消费行为比如用钻石抽卡 在这里我们假设玩家是理性的,即玩家会以追求更高的性价比为目标进行充值与消费(即小R会优先买首冲+月卡,而不是买一个无用的无属性皮肤) 不同类型玩家之间的差异,实际上就主要由这些行为的差异而决定。 注:早期游戏制作的时候,活跃程度也是区分玩家类型的一个重要依据。不过目前现在游戏中有各种手段抹平了不同活跃玩家的差异(体力限制,活跃时间长的收益递减)..

dudu3332的博客 4229

医药领域知识图谱快速及医药问答项目(项目全过程)

该项目是中科院软件所刘焕勇老师在github上的开源项目,基于知识图谱的医药领域问答项目 Github项目地址:mirrors / liuhuanyong / qasystemonmedicalkg · GitCode 一、项目环境搭建 该部分要十分注意,由于版本升级的问题,一些用法及格式已经不兼容了。 python3.8 下载地址:Python Release Python 3.8.10 | Python.orght...

qq_52062182的博客 9917

保姆级教程:在S32K312上配置C40驱动,实现Flash读写(基于RTD 4.4.2)

本文详细介绍了在S32K312微控制器上配置C40驱动实现Flash读写的全流程,基于RTD 4.4.2库。内容涵盖环境搭建、外设配置、Flash操作实战代码及高级应用场景,特别针对LLD驱动和FLS存储操作中的常见问题提供了解决方案,帮助开发者快速掌握嵌入式Flash存储技术。

weixin_28684757的博客 257

告别抖动与滞后:深入博能传动伺服DSC功能,用105报文提升多轴同步性能

本文深入解析博能传动伺服DSC功能如何通过105报文实现多轴同步性能提升,有效解决工业自动化中的抖动与滞后问题。详细介绍了DSC技术原理、105报文实现机制及多轴同步工程实践,帮助工程师优化伺服系统性能,实现绝对齿轮同步。

weixin_30394981的博客 185

IP-Guard分类管理详解

大家都知道在配置IPGUARD策略前需要做分类库进行设置和分类。 1、应用程序:可以分类,例如上班时间只能用OFFICE和WPS,记事本等办公软件,可以在分类里设置一个类 ;办公软件,在未分类里找到OFFICE,WPS等拖入心建的分类里就可以在配置策略里调用。 2、网站分类也不一样,可以按照自己方式自定义。也可以导入厂家已经收集到的网站分类。 3、邮箱分类:可以提前定义好一个或...

IP-Guard专栏 590

jsqlparser 版本不兼容:net.sf.jsqlparser.statement.select.SelectItem 以及 select.SelectBody 解决方法

看Bug直接定位到最后面的错误提示,一开始以为是UnabletostartembeddedTomcat的基本错误,后续发现排查方向错误!问题比较复杂,不过这类问题可看:出现WebServerException:UnabletostartembeddedTomcat解决方法(全)

码农研究僧的博客 2673

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

上一篇: tiger语法分析-修改
be_kind_do
博客等级 码龄9年 2粉丝 3原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值