##
2.1.8 インデント

論理行の行頭にある、先頭の空白 (スペースおよびタブ) の連なりは、 その行のインデントレベルを計算するために使われます。インデントレベルは、 実行文のグループ化方法を決定するために用いられます。

まず、タブは (左から右の方向に) 1 つから 8 つのスペースで置き換えられ、 置き換え後の文字列の終わりの位置までの文字数が 8 の倍数になるように 調整されます (Unixで使われている規則と同じになるよう意図されています)。 次に、空白文字でない最初の文字までのスペースの総数から、その行の インデントを決定します。バックスラッシュを使ってインデントを複数の 物理行に分割することはできません; 最初のバックスラッシュまでの空白が インデントを決定します。

プラットフォーム間の互換性に関する注意: 非 UNIX プラットフォームにおけるテキストエディタの性質上、一つの ソースファイル内でタブとインデントを混在させて使うのは賢明では ありません。また、プラットフォームによっては、最大インデントレベルを 明示的に制限しているかもしれません。

フォームフィード文字が行の先頭にあっても構いません; フォームフィード 文字は上のインデントレベル計算時には無視されます。フォームフィード 文字が先頭の空白中の他の場所にある場合、その影響は未定義です (例えば、スペースの数を 0 にリセットするかもしれません)。

連続する行における各々のインデントレベルは、 INDENT および DEDENT トークンを生成するために使われます。 トークンの生成はスタックを用いて以下のように行われます。

ファイル中の最初の行を読み出す前に、スタックにゼロが一つ積まれ (push され) ます; このゼロは決して除去 (pop) されることはありません。 スタックの先頭に積まれてゆく数字は、常にスタックの末尾から先頭にかけて 厳密に増加するようになっています。各論理行の開始位置において、 その行のインデントレベル値がスタックの先頭の値と比較されます。値が 等しければ何もしません。インデントレベル値がスタック上の値よりも 大きければ、インデントレベル値はスタックに積まれ、INDENT トークンが 一つ生成されます。インデントレベル値がスタック上の値よりも小さい場合、 その値はスタック内のいずれかの値と等しくなければなりません ; スタック上のインデントレベル値よりも大きい値はすべて除去され、 値が一つ除去されるごとに DEDENT トークンが一つ生成されます。ファイルの 末尾では、スタックに残っているゼロより大きい値は全て除去され、 値が一つ除去されるごとに DEDENT トークンが一つ生成されます。

以下の例に正しく (しかし当惑させるように) インデントされた Python コードの一部を示します:

    def perm(l):
            # Compute the list of all permutations of l
        if len(l) <= 1:
                      return [l]
        r = []
        for i in range(len(l)):
                 s = l[:i] + l[i+1:]
                 p = perm(s)
                 for x in p:
                  r.append(l[i:i+1] + x)
        return r

以下の例は、様々なインデントエラーになります:

     def perm(l):                       # error: first line indented
    for i in range(len(l)):             # error: not indented
        s = l[:i] + l[i+1:]
            p = perm(l[:i] + l[i+1:])   # error: unexpected indent
            for x in p:
                    r.append(l[i:i+1] + x)
                return r                # error: inconsistent dedent

(実際は、最初の 3 つのエラーはパーザによって検出されます; 最後の エラーのみが字句解析器で見つかります -- `return r` の インデントは、スタックから逐次除去されていくどのインデントレベル値とも 一致しません)