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