越位规则
越位规则(Off-side rule)是指编程语言中,用缩进来表示块结构的范围。这名词是来自Peter J. Landin,是足球中越位(offside)的双关语。
定义
越位规则,定义于Peter J. Landin在1966年叫做《The Next 700 Programming Languages》的文章中[1]:
“ | 缩排被用来指示程序结构。物理的ISWIM可以依据一个未指明的参数即短语范畴的一个子集来定义,它的实例受到遵从叫做“越位规则”的规则的布局的限制。包含一个短语的第一个符号作为原点的右下象限必定包含整个短语,除了可能的被括号包围的子段落之外。这个规则有三个重要特征:它基于了对齐,而非字符宽度,因而它同等的适合于手写、排字和打字的文本。它的使用不是强制的,它可以自由的同更常规的替代者比如标点符号一起混合使用。还有它是以一种系统性方式结合进入ISWIM中的,这容许了替代者而不改变ISWIM的其他特征,它可以应用于其他语言。 | ” |
这个规则被解读为是一种词法约定:任何非空白记号,当出现在上一行这种记号左侧之时,被接受为一个新宣布的开始[2]。
以Haskell语言的黄金规则为示例:作为某个表达式一部分的代码应该比这个表达式的开始处要缩排进去,即使这个表达式不是此行的最左元素。所有组合起来的表达式必须精确的对齐,在表达式的左侧的所有东西都被当作缩排,即使不是空白。当一个表达式的开始处不是一行的开始的时候,表达式的后续部分可以只比包含这个表达式开始的那一行要缩排进去。由花括号{...}
和分号;
组织起来的代码块可不采用越位规则。下面以将适用越位规则的do
控制结构嵌入if...then...else
为例:
if foo then do first thing second thing third thing else do something_else
if foo then do first thing second thing third thing else do something_else
if foo then do first thing second thing third thing else do something_else
垂直对齐[注 1] 悬挂缩进[注 2] 悬挂缩进[注 3]
- 注释
程序示例
以下是一个Python语言程序的例子,其中用缩进表示其程序区块[3]:
def is_even(a: int) -> bool:
"""确定数a是否是偶数."""
if a % 2 == 0:
print('偶数!')
return True
print('奇数!')
return False
Python中括号内多行代码会隐式的接合在一起,也有着相应的缩排规则:
# 参数比后续部份多一层缩进
def long_function_name(
var_one, var_two, var_three,
var_four):
# 可选的圆括号内后续行多一层缩进,注意这里关键字在行首
if (this_is_first_thing
and that_is_second_thing):
do_something()
# 可选的圆括号内后续行不额外缩进,同类语言元素垂直对齐
elif (this_is_third_thing and
that_is_fourth_thing):
do_something_different()
# 悬挂缩进,参数比行首缩进一层
spam = long_function_name(
arg_one, arg_two,
arg_three, arg_four)
# 按开定界符垂直对齐
eggs = long_function_name(arg_one, arg_two,
arg_three, arg_four)
#可选的闭括号位置
my_list = [
1, 2, 3,
4, 5, 6,
]
# 可选的闭括号位置
my_set = {
1, 2, 3,
4, 5, 6,
}
实现
越位规则可以在词法分析阶段实现,就像Python那样,在这里增加缩进导致词法器输出一个INDENT
记号,而减少缩进导致词法器输出一个DEDENT
记号[4]。这些记号分别对应于使用花括号表示块结构的语言中的开花括号{
和闭花括号}
,并且意味着短语语法不依赖于使用的是缩进还是花括号。这要求词法器保持状态,也就是当前的缩进层级,因而在缩进变更的时候可以检测到,因此这种词法文法不是上下文无关的,INDENT
/DEDENT
依赖于以前缩进层级的上下文资讯。
遵循越位规则的语言
编程语言
其他语言
参考资料
- ^ Landin, P. J. The next 700 programming languages (PDF). Comm. ACM. March 1966, 9 (3): 157–166 [2020-10-11]. doi:10.1145/365230.365257. (原始内容 (PDF)存档于2010-06-20).
Indentation, used to indicate program structure. A physical ISWIM can be defined in terms of an unspecified parameter: a subset of phrase categories, instances of which are restricted in layout by the following rule called "the offside rule." The southeast quadrant that just contains the phrase's first symbol must contain the entire phrase, except possibly for bracketed subsegments. This rule has three important features. It is based on vertical alignment, not character width, and hence is equally appropriate in handwritten, typeset or typed texts. Its use is not obligatory, and use of it can be mixed freely with more conventional alternatives like punctuation. Also, it is incorporated in ISWIM in a systematic way that admits of alternatives without changing other features of ISWIM and that can be applied to other languages.
- ^ off-side rule for FOLDOC. [2020-10-11]. (原始内容存档于2021-01-20).
- ^ Python FAQ on colons. [2012-04-30]. (原始内容存档于2012-02-07).
- ^ Python Documentation (页面存档备份,存于互联网档案馆), 2. Lexical analysis (页面存档备份,存于互联网档案馆): 2.1.8. Indentation (页面存档备份,存于互联网档案馆)
- ^ The Haskell Report - Layout. [2012-04-30]. (原始内容存档于2012-03-31).