越位規則

计算机程序设计术语

越位規則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).