Python 有多少类 BNF 语法规范?

How many BNF-like grammar specifications does Python have?

在 Python 3.9.1 参考文档 'library-3.9.1.pdf' 和 'reference-3.9.1.pdf'(又名 https://docs.python.org/3.9/library/ast.html and https://docs.python.org/3.9/reference/grammar.html)中至少有 3 个类似语法的规范。

有一个“抽象语法”library-3.9.1.pdf, page 1895,看起来像这样:

-- ASDL's 4 builtin types are:
-- identifier, int, string, constant

module Python
{
    mod = Module(stmt* body, type_ignore* type_ignores)
        | Interactive(stmt* body)
        | Expression(expr body)
        | FunctionType(expr* argtypes, expr returns)

    stmt = FunctionDef(identifier name, arguments args,
                       stmt* body, expr* decorator_list, expr? returns,
                       string? type_comment)
          | AsyncFunctionDef(identifier name, arguments args,
                             stmt* body, expr* decorator_list, expr? returns,
                             string? type_comment)
...

有“Python 的 PEG 语法”/“完整语法规范”(“EBNF 和 PEG 的混合体”)(reference-3.9.1.pdf, Chapter 10, pages 111-120 看起来像这样:

# type_expressions allow */** but ignore them
type_expressions:
    | ','.expression+ ',' '*' expression ',' '**' expression 
    | ','.expression+ ',' '*' expression 
    | ','.expression+ ',' '**' expression 
    | '*' expression ',' '**' expression 
    | '*' expression 
    | '**' expression 
    | ','.expression+ 

statements: statement+ 
statement: compound_stmt  | simple_stmts
...

还有各种“BNF 表示法”片段“用于描述语法,而不是词法分析”散布在 eg., reference-3.9.1.pdf, pages 65-108 周围,看起来像这样:

comprehension ::=  assignment_expression comp_for
comp_for      ::=  ["async"] "for" target_list "in" or_test [comp_iter]
comp_iter     ::=  comp_for | comp_if
comp_if       ::=  "if" or_test [comp_iter]

“BNF 表示法”的最后一点似乎对我的目的最有用,看起来与“完整语法规范”非常相似,但它定义了各种句法类型(例如“assignment_expression " 和 "comp_iter"(reference-3.9.1.pdf,第 67 页)),它们在“完整语法规范”或“抽象语法”中均未提及。

所有这些之间的关系是什么,更重要的是,“用于描述语法”的“BNF 表示法”是某种实际规范,还是仅用于参考文件中的阐述?而且,如果它是一个实际的规范,在哪里可以找到它,即作为一个可以方便地解析的文件?

此致!

用于构建 Python 的语法根本不在您的列表中。您可以在源包中以 Grammar/python.gram 的形式找到它。请注意,它有五个不同的开始符号用于不同的编译上下文(完整文件、交互式输入、单个表达式等),尽管大部分语法是共享的。这个语法实际上被解析器生成器用来产生 CPython 实现实际使用的解析器,因此它完美地描述了具体 Python 解释器接受的输入(当然,将来可能会发生变化版本)。如文件顶部附近的注释中所述,语法文件本身的语法在 PEP 中定义。

但它不一定对文档有用,并且在定义语言的意义上,在人们可能期望从语言标准中获得的意义上,它不是确定的。 Python并没有真正标准化,所以要求一个明确的参考语法可能是不合理的。但是分散在 Python 参考手册中的语法可能与您将要获得的一样接近。不过,这些作品仅用于说明性目的,需要将它们与随附的叙述文本一起考虑。 (这通常适用于参考语法,即使是标准化语法,因为 context-free 语法无法捕获任何 real-life 编程语言的所有句法方面,可能有几个例外。所以通常参考一种语言的语法将接受有效程序集的超集,并且标准中的叙述提供了无法在 CFG 中表达的额外约束。)

参考手册末尾收集的语法应该是片段的摘要,但据我了解,它是从 python.gram 文件中机械生成的。所以有可能它与手册中描述的语言之间存在差异。

ast模块文档中列出的抽象文法实际上定义了抽象语法树的结构,所以它根本不是通常意义上的文法(即对线性符号序列的描述)而是一组结构定义,每个结构定义都描述了抽象语法树中类型化节点的性质。它直接对应于您将在使用 ast 模块构建的 AST 中找到的对象,但它不会试图限制正在解析的程序的语法。库引用中的文本是实际源文件 Parser/Python.asdl 的内容,它被机械地处理成 CPython 解析器用来生成 AST 的声明和代码。