【发布时间】:2009-06-09 17:17:57
【问题描述】:
词法作用域如何帮助编译器?对编译或优化有帮助吗?
【问题讨论】:
标签: compiler-construction scope lexical-scope
词法作用域如何帮助编译器?对编译或优化有帮助吗?
【问题讨论】:
标签: compiler-construction scope lexical-scope
我确实认为词法作用域有助于编译器和优化。不过,这取决于您所说的帮助是什么意思。
词法或静态范围允许编译器在本地引用时证明变量的可用性,这意味着在其词法上下文中。它必须在引用变量的方法的范围内。
要在动态范围环境中执行此操作,必须考虑所有调用上下文,因为函数知道其调用上下文也知道的所有变量。为了确保变量可供参考,在编译时需要递归回溯所有调用上下文。
由于这很复杂,编译时会省略,运行时抛出异常。
参见here:相比之下,在动态作用域中,首先在本地函数中搜索,然后在调用本地函数的函数中搜索,然后在调用该函数的函数中搜索,依此类推,调用堆栈。 “动态”指的是变化,因为每次调用给定函数时调用堆栈都可能不同,因此函数可能会根据调用位置而命中不同的变量。
【讨论】:
词法(或静态)作用域减少了编译器将文本正确转换为代码所需的信息量。它可以帮助编译,因为编译器不需要添加必须在运行时访问的附加信息(动态范围就是这种情况)。对于优化,编译器不需要考虑可能存在于其他范围内的变量,因为您可以访问局部变量或全局变量,别无其他。
【讨论】:
词法作用域对编译器或优化代码没有帮助。这是一个语言设计决策。更多解释见this question。
【讨论】:
对于动态范围,许多优化是不可能的,因为您无法保证使优化成为可能的约束。
这在不保证存储大小或表示的动态语言中尤其重要。
例如,动态类型语言的编译器可能能够获取装箱对象的链接列表并将其替换为无符号 8 位字节数组,如果它可以证明列表的元素始终是整数0 和 255。这种东西在你使用得当的情况下很容易用静态作用域证明,并且可以在空间和计算效率上带来巨大的提升。
调试词法范围的代码通常也更容易,因为动态变量在调试中更难追踪。有一种意大利面条式的代码,说明可能在哪里定义了东西,类似于 goto 和过度使用全局变量引起的问题。
【讨论】:
简单地说,词法(或静态)作用域有助于静态类型化语言,动态作用域有助于动态类型化语言。
在动态范围内,变量的范围在运行时被解析。如果在另一个词法环境中使用声明为 int 的变量,其中同名变量的类型为 float。唯一的考虑是它们是两个不同的变量,这意味着变量必须携带类型信息,在大多数静态类型系统中,类型信息根本不进入目标代码。一个程序只有在证明不会发生类型错误的情况下才会简单地编译,然后当然就不再需要类型信息了。
出于这个原因,具有词法范围的动态语言通常需要使用堆而不是堆栈来分配运行时信息。
【讨论】: