编译原理实战课
宫文学
北京原点代码 CEO
26066 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 55 讲
真实编译器解析篇 (19讲)
编译原理实战课
15
15
1.0x
00:00/00:00
登录|注册

18 | Python编译器(二):从AST到字节码

语义检查
符号表的建立过程
符号表结构
窥孔优化
汇编过程
产生指令
建立符号表
检查
优化过程
优化任务
PyCodeObject对象
字节码生成
CFG结构
指令生成
基本块生成
类型检查
引用消解
建立符号表
编译
解析
与Java字节码的比较
字节码特点
窥孔优化
汇编
生成CFG和指令
语义分析
编译过程
Python的字节码
AST到字节码
Python编译器

该思维导图由 AI 生成,仅供参考

你好,我是宫文学。
今天这一讲,我们继续来研究 Python 的编译器,一起来看看它是如何做语义分析的,以及是如何生成字节码的。学完这一讲以后,你就能回答出下面几个问题了:
像 Python 这样的动态语言,在语义分析阶段都要做什么事情呢,跟 Java 这样的静态类型语言有什么不同?
Python 的字节码有什么特点?生成字节码的过程跟 Java 有什么不同?
好了,让我们开始吧。首先,我们来了解一下从 AST 到生成字节码的整个过程。

编译过程

Python 编译器把词法分析和语法分析叫做“解析(Parse)”,并且放在 Parser 目录下。而从 AST 到生成字节码的过程,才叫做“编译(Compile)”。当然,这里编译的含义是比较狭义的。你要注意,不仅是 Python 编译器,其他编译器也是这样来使用这两个词汇,包括我们已经研究过的 Java 编译器,你要熟悉这两个词汇的用法,以便阅读英文文献。
Python 的编译工作的主干代码是在 Python/compile.c 中,它主要完成 5 项工作。
第一步,检查future 语句。future 语句是 Python 的一个特性,让你可以提前使用未来版本的特性,提前适应语法和语义上的改变。这显然会影响到编译器如何工作。比如,对于“8/7”,用不同版本的语义去处理,得到的结果是不一样的。有的会得到整数“1”,有的会得到浮点数“1.14285…”,编译器内部实际上是调用了不同的除法函数。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

Python编译器的编译过程包括词法分析、语法分析和生成字节码。在语义分析阶段,Python编译器建立符号表,进行引用消解和类型检查。符号表是针对每个模块生成的,包括模块、类和函数三种级别的块,构成树状结构。Python的指令一开始是一个字节长的,后来变成了一个字的长度,但仍然习惯上称为字节码。Python的虚拟机是基于栈的虚拟机,指令也很相似于Java。编译器以visit模式遍历整个AST,并建立基本块和指令。基本块是在进入一个作用域的时候生成的,循环语句、if语句还会产生额外的基本块。汇编过程是把每个基本块的指令对象转化成字节码,拼成一个整体,并生成PyCodeObject对象。窥孔优化器在字节码的基础上做了一些优化。总的逻辑是:以visit模式遍历整个AST,并建立基本块和指令。对于每种AST节点,都由相应的函数来处理。Python编译器的优化功能是很有限的。在编译的过程中,Python编译器的优化功能是很有限的。在compiler.c的代码中,你会看到一点优化逻辑。比如,在为if语句生成指令的时候,编译器就会看看if条件是否是个常数,从而不必生成if块或者else块的代码。另一个优化机会,就是在字节码的基础上优化,这就是窥孔优化,其实现是在Python/peephole.c中。它能完成的优化包括:把多个LOAD_CONST指令替换为一条加载常数元组的指令。如果一个跳转指令,跳到return指令,那么可以把跳转指令直接替换成return指令。如果一个条件跳转指令,跳到另一个条件跳转指令,则可以基于逻辑运算的规则做优化。在做优化的时候,窥孔优化器会去掉原来的指令,替换成新的指令。如果有多余出来的位置,则会先填充NOP指令,也就是不做任何操作。最后,扫描一遍整个字节码,把NOP指令去掉,并且调整受影响的jump指令的参数。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《编译原理实战课》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(2)

  • 最新
  • 精选
  • Jacob.C
    答题:因为python变量的语义设计是“定义-使用”,不存在先使用再定义的情况,所以不用担心这种情况下的消解错误
    2020-07-13
    5
  • 思考题:我的理解是Python在添加符号的时候已经通过标志位对符号做了标记,所以后面做引用消解可通过标志位区分。
    2021-07-23
收起评论
显示
设置
留言
2
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部