Compiler construction 编译器构造中的作用域

Compiler construction 编译器构造中的作用域,compiler-construction,Compiler Construction,我正在编写一个编译器,并寻找一种处理作用域的方法 创建一个包含一对值和键的映射堆栈的类是一个好主意吗 当我输入一个新范围时,我会在堆栈顶部插入一个新映射,如果该范围是一个子范围,我会将前一个范围的映射的所有元素复制到新映射。我不建议使用映射,因为它不适用于方法(假设它们是多态的)。我在编译器中所做的是将某个函数传递给一个方法,该方法具有如下方法:resolveMethod等。如果某个作用域无法从resolveField(String name)中找到名为的字段,它会在其父作用域上调用resolv

我正在编写一个编译器,并寻找一种处理作用域的方法

创建一个包含一对值和键的映射堆栈的类是一个好主意吗


当我输入一个新范围时,我会在堆栈顶部插入一个新映射,如果该范围是一个子范围,我会将前一个范围的映射的所有元素复制到新映射。

我不建议使用映射,因为它不适用于方法(假设它们是多态的)。我在编译器中所做的是将某个函数传递给一个方法,该方法具有如下方法:
resolveMethod
等。如果某个作用域无法从
resolveField(String name)
中找到名为的字段,它会在其父作用域上调用
resolveField
,直到根作用域(通常是类)返回
null
,在这种情况下,字段“无法解析”


在内部,我将维护一个字段(和方法,…)列表(如果您的语言支持它们,您无论如何都需要这些字段和方法),而不是映射。然后,
resolveField
将遍历列表,将name参数与实际字段名进行比较,如果名称匹配,则返回字段实例。

处理作用域的方式将取决于您正在编译的语言:对于类C语言。.您不需要将元素复制到新的作用域中(没有嵌套的函数定义,被调用方无法访问调用方的本地变量)。对于类似Pascal的语言,您需要一种访问外部作用域的方法。。这通常是一个指向调用方堆栈框架的指针。最后,如果您正在编译一种允许您构建闭包的语言,那么堆栈思想是不够的。@user1666959它是一种针对包含嵌套函数的语言Tiger的编译器。因此,如果我py嵌套函数的上一个堆栈,而不是简单地有一个指向它的指针,性能会更差,但它仍然可以工作,对吗?啊,Appel的东西。不记得语法,但是考虑一下:fun f1(){fun f2{fun f3(){}}.你要把f1的变量复制到f2,然后所有的变量都复制到f3吗?别忘了相互递归函数:fun MR{fun f1(){…f2…}fun f2(){…f3…}fun f3(…f1…f2){}。为什么你说映射不适用于方法?是因为你正在编译的语言是多态的吗?据我所知,tiger不是。即使如此,映射可以通过将名称映射到可能的定义列表来帮助减少搜索空间。映射有很大的开销,但如果范围中有很多名称,则查找速度会更快这将是一场胜利。