3

原谅我的英语。我最近试图了解编译器的不同部分并用一种游戏语言来实现它们。我想知道语义分析器的工作是什么,因为我读到的许多语义分析器应该做的事情并不是真正适用于动态语言,例如类型检查、范围检查等,因为这些事情是在运行时检查的时间。

所以我认为动态语言(如 LUA 或 PYTHON 或 RUBY)的语义分析器的一些工作是

  1. 确保分配不错,例如 1 = a 或 5 = 5

但是,我不确定动态语言编译器的语义分析阶段还有哪些其他工作。似乎它在动态语言中的工作量很小,因为大部分工作都是在运行时完成的。语义分析器还为动态语言处理了哪些其他常见工作?我觉得我错过了语义分析的大部分内容。谢谢你。

4

1 回答 1

4

没错,动态语言编译器中不存在许多分析任务(这就是它们实现相对简单的原因)。但是,我还能想到更多任务:

  • 范围界定。动态确定变量的类型甚至有时甚至存在是正确的,但至少对于 Lua 和 Python,范围的某些部分可以(如果您不想使实现不必要地复杂化,则应该)在以下位置完成编译时:非全局变量的范围。

    • 需要分析什么?这部分在 Lua 中很容易,因为它有一个显式的local关键字——但它仍然需要编译器知道它!- 并且需要在 Python 中进行相对广泛的分析,赋值隐式地使变量成为局部变量和两个(在 3.x 中,一个在 2.x 中)关键字来改变这种行为。

    • 为什么这有关系?在 Python 中,访问尚未初始化的局部变量与访问 Python 中不存在的全局变量一样多,但错误不同。在 Lua 中,两者都会导致nil并且local不会改变先前赋值的范围,但是后续读/写的语义仍然会发生变化。此外,在这两种情况下,字节码指令也非常不同。

  • 优化。好吧,显然您只能获得有限的(如果有的话,在某些情况下)关于哪些变量/“常量”包含的信息。尽管如此,至少 CPython 有各种各样的常量折叠和字节码优化通道(参见peephole.c),甚至 Lua 及其异常快速的一次性编译器也对算术指令进行了一些常量折叠。PyPy 解释器(独立于其 JIT)引入了一个CALL_LIKELY_BUILTIN操作码,该操作码是为调用全局变量而发出的,按其名称,可能是内置函数。很明显,这需要一些范围分析。

  • 正如您自己所说,抱怨编译时禁止的少数构造。但是,这也可以计入解析(其中许多规则实际上是在语法中编码的)。另一个例子(在语法中不容易编码)是重复的函数参数名称。

于 2011-08-25T06:44:50.037 回答