Python解析器如何处理缩进?

tem*_*def 22 python whitespace parsing

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

if (x == 5) {
    a = b;
    c = d;
}
Run Code Online (Sandbox Code Playgroud)

解析器可以告诉它a = b;并且c = d;是单个表达式的一部分,因为块周围有一组明确的大括号.此外,解析器知道块中的两个语句是相关的,因为它们之间有分号.这可以使用以下内容轻松编码为CFG:

STMT        ::=  IF_STMT | EXPR; | BLOCK_STMT | STMT STMT
IF_STMT     ::=  if ( EXPR ) STMT
BLOCK_STMT  ::=  { STMT }
Run Code Online (Sandbox Code Playgroud)

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

if x == 5:
    a = b
    c = d
Run Code Online (Sandbox Code Playgroud)

尽我所能,我看不到写一个接受这个的CFG的方法,因为我无法弄清楚如何将"嵌套的两个语句"编码成CFG.

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

Nou*_*him 21

缩进由两个"伪标记"处理 - INDENT和DEDENT.还有一些细节在这里.有关更多信息,您应该查看python tokeniser和parser的源代码.