“CPS 使异常、非局部跳转和一等控制成为显式函数调用,也常用作编译器中间表示。对有限种续延函数做 defunctionalization,可把它们变成抽象机器的帧;这解释了显式控制栈如何由高…”
形式陈述 ​
抽象机器是一类以配置集合
一条机器规则只检查有限的当前状态并完成一个局部动作,例如查找变量、把待求值子项压成帧、分配位置或把值交给续延。它属于操作语义,但机器转移不是源语言语法归约的别名。若解码函数
并另证源语义的每个相关步骤能由零步或多步机器转移模拟。只有两边的步进粒度和可观察状态确实匹配时,才能加强为逐步模拟或双模拟;不能只因最终值相同便声称转移一一对应。
抽象机器可由语义导出,而不必凭经验拼装。一个常见路线把高阶求值器的控制流改写成 CPS,再对有限种续延函数做 defunctionalization,把函数闭包变成带标签的数据帧;源语言使用词法绑定时,闭包转换还会显式化自由变量环境。这条路线解释了机器字段的来源,但不是所有机器都必须按同一编译流水线构造。
直觉 ​
直接求值器把“下一步回来做什么”藏在宿主语言的调用栈里。抽象机器把这段隐含控制摊开:当前子表达式放在 control 中,尚未完成的外层工作放进帧,名字解析交给环境,需要共享可变数据时再加入 store。于是一次递归函数调用变成一次明确的状态转移,整个求值过程成为可检查的轨迹。
“抽象”表示机器忽略真实处理器的寄存器、缓存和指令编码,只保留所研究语言行为所需的状态。它仍可比直接语法归约更接近解释器实现,却不能用“更低级”替代正式的配置定义与语义对应。
例子与边界 ​
考虑表达式
一个左到右栈机器可采用四条转移:
求值 addL 帧中;左侧得到
同一种 λ 语言既可有直接替换机器,也可有把变量映到闭包的环境机器;带引用时才通常需要 store。抽象机器的状态空间还可能无限,因为控制项、环境、地址或栈没有有限上界。因此它不是自动机理论中有限状态自动机的同义词,也不会仅因名字里有“机器”就给出实际时间成本。
推论与应用 ​
抽象机器在语言定义与实现之间提供可证明的中间层。显式帧适合说明求值顺序、异常展开、尾调用与一等续延;加入存储后还能描述可变引用以及地址分配。具体的 CEK、CESK 与 SECD 机器是在这套框架中选择特定配置和转移规则的实例,而非抽象机器的完整定义。
机器语义也为抽象解释和控制流分析提供起点:若把无限的地址、环境或值域有限近似化,同一转移结构可变成静态分析。不过近似会合并状态,必须另证可靠性,不能把具体执行机直接称为分析算法。
参考资料
- John C. Reynolds, “Definitional Interpreters for Higher-Order Programming Languages,” ACM Annual Conference, 1972。
- Olivier Danvy and Lasse R. Nielsen, “Defunctionalization at Work,” PPDP, 2001。
- Matthias Felleisen and Daniel P. Friedman, “Control Operators, the SECD-Machine, and the λ-Calculus,” in Formal Description of Programming Concepts III, 1986。