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

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

  • 确保分配不会像 1 = a 或 5 = 5 那样糟糕

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

    最佳答案

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

  • 范围。变量的类型和有时甚至存在是动态确定是正确的,但至少对于 Lua 和 Python,范围界定的某些部分可以(如果您不想不必要地使实现复杂化,应该这样做)在编译时间:非全局变量的范围。
  • 需要分析什么?这部分在 Lua 中很容易,因为有一个显式的 local 关键字 - 但它仍然需要编译器意识到它! - 并且需要在 Python 中进行相对广泛的分析,赋值隐式地使变量成为局部变量和两个(在 3.x 中,在 2.x 中一个)关键字来改变这种行为。
  • 为什么重要?在 Python 中,访问尚未初始化的局部变量与访问 Python 中不存在的全局变量一样严重,但又是不同的错误。在 Lua 中,两者都导致 nillocal 不会改变先前赋值的范围,但后续读/写的语义仍然改变。此外,两种情况下的字节码指令也大不相同。
  • 优化。好吧,显然您只能获得有关哪些变量/“常量”包含的有限信息(如果有的话,在某些情况下)。尽管如此,至少 CPython 有各种各样的常量折叠和字节码优化 channel (参见 peephole.c ),甚至 Lua 及其非常快的单 channel 编译器也会对算术指令进行一些常量折叠。并且 PyPy 解释器(独立于它的 JIT)引入了一个 CALL_LIKELY_BUILTIN 操作码,它是为调用全局变量而发出的,根据它们的名字,可能是内置函数。很明显,这需要一些范围分析。
  • 正如你自己所说,提示在编译时被禁止的少数构造。但是,这也可以在解析中计算(其中许多规则实际上已编码在语法中)。另一个例子(不容易在语法中编码)是重复的函数参数名称。
  • 关于compiler-construction - 动态语言中语义分析器的工作是什么?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/7185225/

    10-11 22:15
    查看更多