3 语义分析
语义分析阶段的任务是:将变量的定义与它们的各个使用联系起来,检查每一个表达式是否有正确的类型,并将抽象语法变为更简单的更适合生成机器代码的表示。
3.1 符号表
符号表是绑定的集合。这些绑定是标识符与其含义的一种映射关系。因为作用域的改变,符号表也随之改变。如下面的c语言
struct M {
static int a = 5;
struct N{
static int b = 10;
static char a;
}
}
上面代码的符号表可能为:
T1 = {a--àint}
T2= { b--àint, a--àchar}
3.2 命令式符号表
这种表具有破坏恢复的功能。假设从符号表T1到T2,它们有相同的符号,在T1的时候S---->type1,在T2的时候,S---->type2。在T2的时候,查询到的S的信息为S---->type2,这称为破坏。当T2的作用域终止的时候,符号表要能恢复到T1的符号表,这个行为称为恢复。
那么这个符号表提供一下对外接口:
查找,插入,作用域开始,作用域结束。
在实现上它即是一个hash表(查找),又是一个栈(恢复)。
3.3 表达式的类型检查
见书上详述
3.4 变量的类型检查
见书上详述
3.5 声明的类型检查
见书上详述
补充的是对于递归类型
type tree = {key:int, children:treelist}
type treelist = {hd:tree, tl:treelist}
书中认为中间插入一句别的语句就是非法的,即下面的描述是非法的。
type tree = {key:int, children:treelist}
var a:int = nil
type treelist = {hd:tree, tl:treelist}
我把这个要求去了,改为在同一个作用域里面,所有的类型都提前声明了。也就是在语义分析type tree = {key:int, children:treelist}这句的时候,treelist的类型已经声明过了。