tiger 语义分析(类型检查)

来源:互联网 发布:parsley.js ajax 编辑:程序博客网 时间:2024/04/29 10:02

为编译器实现类型检查。
在语法分析的基础上,对抽象语法树进行类型检查,并生成相关报错信息。

完成语法分析的基础上,还需:
types.[ch]: 已给出,描述了tiger语言的数据类型
env.[ch]: 实现值环境、类型环境
semant.[ch]:实现类型检查函数SEM_transProg(A_exp exp)
semtest.c: 测试平台,main入口
修改makefile

实现方法:
1. 类型检查过程中,遇到声明时,将其按规则检查并构造,放入相应值或类型环境中,遇到类型、变量或函数标示符时在这两个环境中查找。初始tenv中包含int、string两种基本类型,venv包含print,ord等预定义函数。
2. 表达式根据不同类型作相应处理,例如exp1:=exp2要保证exp1和exp2类型相同。特别声明了void类型用于匹配无值表达式,方便处理。
3. 作用域处理。可以通过在环境中插入一个标记实现。作用域开始,插入一个标记,作用域结束,弹出标记以上的所有新增声明或定义。

注意:
1. for、while、if-then等表达式无值返回,需要判断。
2. nil类型只能用于给记录(record)类型赋值或比较,两个nil比较非法。
3. tiger语言中定义的两个数组(array)或记录,即使各个域相同,也不具有等价性。

例如:
type a = {x:int, y:int}
type b = {x:int, y:int}
a和b为两种类型,不能相互赋值。
而 name类型
type a = {x:int, y:int}
type b =a
a和b视为相同类型。
由此可以容易的实现类型比较,类型构建后都对应唯一的数据结构,只需比较两个非name类型的指针是否相等即可。
-
4. 递归类型和函数声明。 递归类型可以先向环境插入(type_id, Ty_Name(type_id, NULL))项,然后再构造相应结构,替换原来的NULL。递归函数声明类似。
5. 重声明。连续的递归声明中不允许出现重复声明,而其他情况下可以,后来声明会覆盖前面的。
6. break嵌套。用一全局变量loop保存循环嵌套层数,只要在循环中,break就合法。
7. 作用域。除let表达式,函数形参中存在声明,需要作用域规则,for中循环变量也是。
8. for中循环变量不能赋值(未实现,没想到代价比较小的方法)

代码实现:
点我

0 0