所以我认为动态语言(如LUA或PYTHON或RUBY)的语义分析器的一些工作是
但是,我不确定动态语言编译器的语义分析阶段还有哪些其他工作。看起来它在动态语言中的工作量非常小,因为大多数都是在运行时完成的。语义分析器还为动态语言做了哪些其他常见工作?我觉得因为我错过了语义分析的大部分内容。谢谢。
答案 0 :(得分:4)
你是对的,动态语言编译器中不存在许多分析任务(这就是为什么它们实现起来相对简单)。但是,还有一些我能想到的任务:
作用域。变量的类型,有时甚至存在是动态确定的是正确的,但至少对于Lua和Python来说,有一些范围可以(并且如果你不想让实现不必要地复杂化),可以在编译时间:非全局变量的范围。
需要分析什么?这部分在Lua中很容易,因为有一个明确的local
关键字 - 但它仍然需要编译器知道它! - 并且需要在Python中进行相对广泛的分析,分配隐式地使变量本地化和两个(在3.x中,一个在2.x中)关键字来改变该行为。
为什么重要?在Python中,访问尚未初始化的局部变量与在Python中访问不存在的全局错误一样多,但是出现了不同的错误。在Lua中,导致nil
和local
都不会改变先前赋值的范围,但后续读/写的语义仍然会发生变化。此外,字节码指令在两种情况下都非常不同。
优化。好吧,显然你只能有限(如果有的话,在某些情况下)有关变量/“常量”包含的信息。尽管如此,至少CPython有各种常量折叠和字节码优化传递(参见peephole.c),甚至Lua及其疯狂快速的单程编译器也会对算术指令进行一些常量折叠。而且PyPy解释器(独立于它的JIT)引入了一个CALL_LIKELY_BUILTIN
操作码,该操作码用于调用全局变量,根据它们的名称,它们可能是内置函数。很明显,这需要进行一些范围分析。
正如你自己所说,抱怨在编译时被禁止的一些构造。但是,这也可以在解析下计算(其中许多规则实际上是在语法中编码的)。另一个例子(在语法中不容易编码)是重复的函数参数名称。