缩进是如何解析的
在解析之前,空格由词法分析器处理。
词法分析器使用堆栈来存储缩进级别。在开始时,堆栈只包含值 0,这是最左边的位置。每当嵌套块开始时,新的缩进级别被推入堆栈,并且 INDENT
标记被插入到令牌流中,该令牌流被传递给解析器。一行中永远不会有多个 INDENT
标记(IndentationError
)。
当遇到具有较小缩进级别的行时,将从堆栈中弹出值,直到值在顶部,该值等于新缩进级别(如果未找到,则发生语法错误)。对于弹出的每个值,将生成 DEDENT
标记。显然,连续可能有多个 DEDENT
令牌。
词法分析器会跳过空行(仅包含空格和可能的注释),并且永远不会为它们生成 INDENT
或 DEDENT
标记。
在源代码的末尾,为堆栈上剩下的每个缩进级别生成 DEDENT
标记,直到只剩下 0。
例如:
if foo:
if bar:
x = 42
else:
print foo
分析如下:
<if> <foo> <:> [0]
<INDENT> <if> <bar> <:> [0, 4]
<INDENT> <x> <=> <42> [0, 4, 8]
<DEDENT> <DEDENT> <else> <:> [0]
<INDENT> <print> <foo> [0, 2]
<DEDENT>
解析器将 INDENT
和 DEDENT
标记作为块分隔符处理。