> 文章列表 > 语义分析- 其他问题

语义分析- 其他问题

语义分析- 其他问题

语义分析中要考虑的其他问题:

  • 类型相容性?
  • 错误诊断?
  • 代码翻译?

1、类型相等

类型检查问题往往归结为判断两个类型是否相等t1 == t2?

在实际的语言中,这往往是个需要谨慎处理的复杂问题。

示例1:名字相等 VS 结构相等

对采用名字相等的语言,可直接比较

对采用结构相等的语言,需要递归比较各个域

struct A
{int i;
} x;struct B
{int i;
} y;x = y;

我们可以看到上述代码中,x与y的存储结构是一样的,都是一个4字节的整形域i(32位机器上),那么把y赋值给x这样的操作合法吗?

这个问题取决于研究的语言的语义,如果这个语言的语义采用的是名字相等的策略,那么这样的赋值就是非法的,因为y的类型名字是B,x的类型名字是A,类型名字是不一样的,所以这样的赋值是不能做的;但如果采用结构相等的语言,两侧同为结构体类型,我们需要看每个域,域的个数是不是一样,每个域是不是可以分别赋值,可能需要递归的来比较各个域。

示例2:面向对象的继承

需要维护类型间的继承关系

class A
{int i;
}class B extends A
{int i;
}A x;
B y;
x = y;

子类对象y赋给父类对象x,如果只看类型的话,y的类型是B,x的类型是A,也是不相等的,所以在面向对象语言中,为了这种类型检查可以通过,需要维护类型间的继承关系,在Java中,继承是一棵树状的关系,任何子类对象都可以赋给父类对象。面向对象中,子类到父类的转换称为向上转型。

2、错误诊断

(1)要给出尽可能准确的错误信息

(2)要给出尽可能多的错误信息

  • 从错误中进行恢复

(3)要给出可能准确的出错位置

  • 程序代码的位置信息要从前端保留并传递过来

3、代码翻译

现代的编译器中的语义分析模块,除了做语义分析外,还要负责生成中间代码或目标代码

代码生成的过程也同样是对树的某种遍历。

因此,语义分析模块往往是编译器中最庞大也最复杂的模块。