越位规则

计算机程序设计术语

越位規則Off-side rule)是指程式語言中,用縮排來表示块结构的範圍。這名詞是來自Peter J. Landin,是足球越位(offside)的雙關語。

定义

越位规则,定义于Peter J. Landin在1966年叫做《The Next 700 Programming Languages》的文章中[1]

这个规则被解读为是一种词法约定:任何非空白记号,当出现在上一行这种记号左侧之时,被接受为一个新宣布的开始[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]
注释
  1. ^ 组合起来的同类短语必须精确的对齐。
  2. ^ 从在行首的符号then所属的短语的角度看,和从不在行首的do所属的短语的角度看,都是悬挂缩进。
  3. ^ 从在行首的符号then所属的短语的角度看是悬挂缩进;从不在行首的do所属的短语的角度看,缩进区块相当于用括号包围起来的除外情况。

程式範例

以下是一個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依赖于以前缩进层级的上下文信息。

遵循越位規則的語言

编程语言

其他语言

參考資料

  1. ^ 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. 
  2. ^ off-side rule for FOLDOC. [2020-10-11]. (原始内容存档于2021-01-20). 
  3. ^ Python FAQ on colons. [2012-04-30]. (原始内容存档于2012-02-07). 
  4. ^ Python Documentation页面存档备份,存于互联网档案馆), 2. Lexical analysis页面存档备份,存于互联网档案馆): 2.1.8. Indentation页面存档备份,存于互联网档案馆
  5. ^ The Haskell Report - Layout. [2012-04-30]. (原始内容存档于2012-03-31).