已经探究了编译器用来进行语法分析的机制以及必须生成目标机器代码的特性。我们现在返回到语言设计中的核心问题。具体来说,本章讨论控制流问题,或者叫做程序执行顺序。顺序对于大多数计算模型是很重要的。决定了为了完成一些任务,那条指令先执行,那条后执行。我们可以将语言中顺序的机制划分几类:

  1. Sequencing:statement 按照确定顺序执行(或者 expression evaluated),通常就是程序呈现的顺序
  2. Selection:根据执行期间的条件,在两个或者多个 statement 或 expression 之间选择。最常见的选择结构是 if case(switch) statement。选择有时候也被称为 alternation
  3. Iteration:给定的代码片段重复执行特定次数或者满足执行期间的条件。迭代结构包括 for/do, while, repeat
  4. Procedural abstraction:一系列复杂控制结构的封装(subroutine ),可以作为单独的单元,而且可以接受参数
  5. Recursion:expression 被自己直接或者间接定义;计算模型使用栈来保存部分计算信息。递归通常使用子引用 subroutine 来定义
  6. Concurrency:两个或者多个程序片段“同时”执行,要不在不同处理器分开执行,要不在同一处理器实现相同的并行效果
  7. Exception handling and speculation:程序片段假定一些条件为真乐观执行,如果条件为假,执行分支转到执行保护片段(excepiton handling),或者代替为保护片段(speculation)。对于 speculation,语言实现必须可以 undo,或者 “roll back”被保护代码的可见部分。
  8. Nondeterminacy:statement 或者 expression 的顺序或者选择故意不指定,表示都可以导致正确结果。从某种意义上来说,有些语言要求选择随机公平。

尽管句法和语法细节语言之间大有不同,但这些类别的顺序控制结构可以在大多数语言中发现。一个程序猿如果从这些类别来学习新语言,评估语言之间设计的权衡,算法的选择,而不是陷入到语言的语法细节中会更容易。

Subroutines 是第9章的内容,并发是第 13 章的内容。异常处理在 9.4 和 13.4.4 中会分别讨论。本章会讨论剩下的几种类别。在 6.1 我们来讨论表达式的求值(expression)-- 所有高级顺序的基础表达块。来讨论 expression 的句法表示,操作符的优先级和关联性,操作数的执行顺序以及赋值的语法。尤其需要关注的是关联值的变量和关联引用的变量之间的区别。在 6.2 我们讨论结构化和非结构化(goto)的控制流程。

不同类别的控制流在不同语言中的重要性差别很大。sequencing 是命令式语言(冯诺依曼,面向对象语言)的核心,但是在函数式语言中的角色就小一些,函数式语言强调 evaluation of expression,否定或者消除影响程序输出的 statements。类似的,函数式语言大量使用递归,命令式语言更喜欢迭代。逻辑语言倾向于消除或者隐藏顺序控制:开发者描述推理规则,语言实现负责找到应用这些规则的顺序。