CPython 实现原理
  • README
  • 一、简介
    • 1.1 如何使用此书
    • 1.2 额外材料和学习资料
  • 二、获取 CPython 源码
    • 2.1 源代码里有什么?
  • 三、准备你的开发环境
    • 3.1 选IDE还是编辑器?
    • 3.2 安装Visual Studio
    • 3.3 安装Visual Studio Code
    • 3.4 安装JetBrains Clion
    • 3.5 安装Vim
    • 3.6 总结
  • 四、编译 CPython
    • 4.1 在 macOS 上编译 CPython
    • 4.2 在 Linux 上编译 CPython
    • 4.3 安装自定义版本
    • 4.4 make 快速入门
    • 4.5 CPython 的 make 目标
    • 4.6 在 Windows 上编译 CPython
    • 4.7 PGO 优化
    • 4.8 总结
  • 五、Python 语言和语法
    • 5.1 为什么 CPython 是用 C 语言而不是用 Python 语言来实现
    • 5.2 Python 语言规范
    • 5.3 分析器生成器
    • 5.4 重新生成语法
    • 5.5 总结
  • 六、配置和输入
    • 6.1 配置状态
    • 6.2 构建配置
    • 6.3 从输入构建模块
    • 6.4 总结
  • 七、基于语法树的词法分析和解析
    • 7.1 具象语法树生成器
    • 7.2 CPython 解析器-分词器
    • 7.3 抽象语法树
    • 7.4 要记住的术语
    • 7.5 一个示例:添加一个约等于比较运算法
    • 7.6 总结
  • 八、编译器
    • 8.1 相关源文件
    • 8.2 重要的专业术语
    • 8.3 实例化一个编译器
    • 8.4 未来标志和编译器标志
    • 8.5 符号表
    • 8.6 核心编译过程
    • 8.7 汇编
    • 8.8 创建一个 Code Object
    • 8.9 使用 Instaviz 展示 Code Object
    • 8.10 一个示例:实现约等于操作符
    • 8.11 总结
  • 九、求值循环
    • 9.1 构建线程状态
    • 9.2 构建帧对象
    • 9.3 帧的执行
    • 9.4 值栈
    • 9.5 例子:在列表中添加元素
    • 9.6 总结
  • 十、内存管理
    • 10.1 C 中的内存分配
    • 10.2 Python 内存管理系统设计
    • 10.3 CPython 内存分配器
  • 十一、并行和并发
    • 11.1 并行和并发模型
    • 11.2 进程的结构
    • 11.3 多进程并行
    • 11.4 多线程
    • 11.5 异步编程
    • 11.6 生成器
    • 11.7 协程
    • 11.8 异步生成器
    • 11.9 子解释器
    • 11.10 总结
  • 十二、对象和类型
    • 12.1 本章的例子
    • 12.2 内置类型
    • 12.3 对象和可变长度对象类型
    • 12.4 类型类
    • 12.5 布尔和整数类型
    • 12.6 Unicode 字符串类型
    • 12.7 字典类型
    • 12.8 总结
  • 十三、标准库
    • 13.1 Python 模块
    • 13.2 Python 和 C 模块
  • 十四、测试套件
    • 14.1 在 Windows 上运行测试套件
    • 14.2 在 Linux 或 MacOS 上运行测试套件
    • 14.3 测试标志
    • 14.4 运行特定测试
    • 14.5 测试模块
    • 14.6 测试工具
    • 14.7 总结
  • 十五、调试
  • 十六、基准测试、性能分析和追踪
  • 十七、下一步计划
    • 17.1 为 CPython 编写 C 扩展
    • 17.2 改进你的 Python 应用程序
    • 17.3 为 CPython 项目做贡献
    • 17.4 继续学习
  • 十八、附录
    • 18.1 C 预处理器
    • 18.2 基础 C 语法
    • 18.3 总结
  • 致谢
Powered by GitBook
On this page
  • 语言说明文档
  • 示例
  • 语法文件
  • 一个例子:while 语句
Edit on GitHub
  1. 五、Python 语言和语法

5.2 Python 语言规范

CPython 源码中包含了 Python 语言的定义,其作为参考规范供所有 Python 解释器使用。

此规范使用了人机可读的文件格式。文档内是对 Python 语言的详细解释,概述了允许的内容以及每个语句的行为。

语言说明文档

Doc/reference 目录包含了 Python 语言特性的介绍。

此目录中有你要了解的整个语言、结构体和关键词的文件:

图片文字翻译:

compound_stmts.rst:if、while、for 和函数定义等复合语句

datamodel.rst:对象、值和类型

executionmodel.rst:Python 程序的结构

expressions.rst:Python 表达式的元素

grammar.rst:Python 的核心语法(引用 Grammar/Grammar)

import.rst:import 系统

index.rst:语言参考索引

introduction.rst:参考文档介绍

lexical_analysis.rst:词法结构,如行、缩进、单词符号和关键字

simple_stmts.rst:assert、import、return 和 yield 等简单语句

toplevel_components.rst:说明执行 Python 的方法,如脚本和模块

示例

在 Doc/reference/compound_stmts.rst 中,你可以看见一个定义 with 语句的简单例子。

with 语句有很多用法,最简单的用法是上下文管理的实例化和嵌套代码块:

with x():
    ...

你可以使用 as 关键词将结果赋值给变量:

with x() as y:
    ...

你还可以使用逗号将上下文管理器连接起来:

with x() as y, z() as jk:
    ...

此文档包含了用户可读的语言规范,而机器可读的规范位于Grammar/python.gram 中。

语法文件

Python 语法文件使用解析表达式语法规范。在语法文件中,你可以使用如下符号:

  • * 用于零次或多次重复;

  • + 用于一次或多次重复;

  • [] 用于可选部分;

  • | 用于可选择项;

  • () 用于定义优先级。

举一个实例的例子来说明,如果让你定义一杯咖啡,你会怎么来定义:

  • 它一定有一个杯子;

  • 它必须包含一杯及以上的浓咖啡;

  • 它可以有牛奶,但此项是可选择的;

  • 它可以有水,但此项是可选择的;

  • 如果它包含牛奶,那么牛奶可以是多种多样的,如:全脂牛奶,脱脂牛奶以及豆奶。

用 PEG 来定义一杯咖啡,一份咖啡订单看起来是这样的:

参见

CPython 3.9 的源代码有两个语法文件。一种传统语法是用一个被称为 BNF 范式的上下文无关文法所编写。 CPython 3.10 已经删除了 BNF 语法文件(Grammar/Grammar)。 BNF 不是 Python 语言特有的,许多其他语言也用 BNF 作为语法符号。

在铁路图中,每个可能的组合都必须要从左到右排成一行。其中可选的语句可以被绕过,而一些语句可以形成循环。

一个例子:while 语句

while 语句有多种形式。最简单的形式包含了一个表达式,然后是一个 : 终结符号以及一个代码块:

while finished == True:
    do_things()

或者,你可以使用一个赋值表达式,它在语法中被称为 named_expression。这是 Python 3.8 的新增特性:

while letters := read(document, 10):
    print(letters)

此外,while 语句后面还可以跟一个 else 语句和代码块。

while item := next(iterable):
    print(item)
    else:
        print("Iterable is empty")

如果你在语法文件中搜索 while_stmt,则会看到如下定义:

while_stmt[stmt_ty]:
| 'while' a=named_expression ':' b=block c=[else_block] ...

引号中的任何内容都是字符串文字,被称为终结符号。 终结符号用于识别关键字。

这两行定义还引用了另外两个定义:

  1. block 是指包含一个及以上语句的代码块;

  2. named_expression 指的是一个简单表达式或者一个赋值表达式。

用铁路图来展示,while 语句如下所示:

图片不翻译

作为一个更加复杂的案例,try 语句在语法中的定义如下所示:

图片不翻译

try 语句有有两种用法:

  1. try 只有一个 finally 语句;

  2. try 有一个或多个 except 从句,后面跟一个可选的 else , 然后是一个可选的 finally。

用铁路图来展示,如下图所示:

图片不翻译

try 语句是一个更加复杂的优秀示例。

如果你想详细了解 Python 语言,那就通读定义在 Grammar/python.gram 中的语法。

Previous5.1 为什么 CPython 是用 C 语言而不是用 Python 语言来实现Next5.3 分析器生成器

Last updated 2 years ago

在本章节,你将使用铁路图来展示语法。下图是定义咖啡语句的铁路图。