Python解析器如何处理缩进?

时间:2011-06-21 18:38:01

标签: python parsing whitespace

在解析像C这样的自由格式语言时,解析器很容易通过查看解析器发出的符号来确定多个表达式何时彼此相关。例如,在代码中

if (x == 5) {
    a = b;
    c = d;
}

解析器可以告诉a = b;c = d;是同一个块语句的一部分,因为它们被大括号包围。这可以很容易地使用类似的东西编码为CFG:

STMT        ::=  IF_STMT | EXPR; | BLOCK_STMT | STMT STMT
IF_STMT     ::=  if ( EXPR ) STMT
BLOCK_STMT  ::=  { STMT }

在Python和其他对空格敏感的语言中,这样做并不容易,因为语句的结构只能从它们的绝对位置推断出来,我认为不能很容易地将它编码成CFG。例如,Python中的上述代码如下所示:

if x == 5:
    a = b
    c = d

尽可能地尝试,我看不到写一个接受这个的CFG的方法,因为我无法弄清楚如何将“嵌套的两个语句”编码成CFG。

Python解析器如何对语句进行分组?他们是否依赖于扫描仪自动插入表示语句开头和结尾的额外标记?他们是否为程序产生了一个粗略的AST,然后有一个额外的传递,根据它们的缩进汇总语句?我是否缺少一个聪明的CFG来解决这个问题?或者他们使用比标准LL(1)或LALR(1)解析器更强大的解析器,它能够考虑空白级别?

1 个答案:

答案 0 :(得分:21)

缩进由两个“伪标记”处理 - INDENT和DEDENT。有一些细节here。有关更多信息,您应该查看python tokeniser和parser的源代码。