最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

[oeasy]python0135_python_語(yǔ)義分析_ast_抽象語(yǔ)法樹(shù)_abstract_syntax_tree

2023-04-16 17:11 作者:oeasy  | 我要投稿

語(yǔ)義分析_抽象語(yǔ)法樹(shù)_反匯編

回憶

  • 上次回顧了一下歷史

    • python 是如何從無(wú)到有的

    • 看到 Guido 長(zhǎng)期的堅(jiān)持和努力

  • python究竟是如何理解

    • print("hello")的?

    • 這些ascii字母如何被組織起來(lái)執(zhí)行?

純文本

  • 首先編寫(xiě)Guido的簡(jiǎn)歷

print("1982------Guido in cwi")print("1995------Guido in cnri")print("2000------Guido in beopen")print("2005------Guido in google")print("2012------Guido in dropbox")print("2020------Guido in microsoft")
  • 并保存為Guido.py

生成token流

  • 回到shell之后

    • 從字符流生成token流

  • 這個(gè)過(guò)程叫做分詞

分詞

  • 首先把一個(gè)個(gè)字符組成詞

  • 分析一下哪些字可以組成詞

    • 術(shù)語(yǔ)叫詞法分析(lexical analysis)

  • 詞分析出來(lái)之后呢?

組詞

  • 詞分析出來(lái)就是怎么組詞的問(wèn)題

    • 哪些詞和哪些詞先組合

    • 哪些詞和哪些詞后組合

  • 生成一棵抽象語(yǔ)法樹(shù)

    • AST(Abstract Syntax Tree)

  • 我能看看這棵ast樹(shù)么?

引入ast模塊

  • 具體怎么做呢?

流程

  • 先把這個(gè)ast模塊導(dǎo)入(import)進(jìn)來(lái)

    • 第一句就是import ast

    • 回車之后沒(méi)有任何報(bào)錯(cuò)

    • 那就是執(zhí)行成功了

    • 后面也一樣

    • 沒(méi)有報(bào)錯(cuò)就是執(zhí)行成功了

  • 然后讀取guido.py并送到s

  • 然后對(duì)于s進(jìn)行語(yǔ)法分析(parse)

  • 再把分析(parse)的結(jié)果進(jìn)行轉(zhuǎn)儲(chǔ)(dump)

  • 看起來(lái)有點(diǎn)亂

    • 可以清晰一些么?

升級(jí)Python

  • 目前l(fā)anqiao.cn上面的python是3.8

  • 這個(gè)清晰縮進(jìn)的格式需要在3.9以上完成

  • 需要升級(jí)

sudo apt updatesudo apt install python3.9
  • 升級(jí)之后就可以使用Python3.9了

縮進(jìn)換行

  • 只能在本地演示一下

  • 這個(gè)就是把詞組成語(yǔ)法樹(shù)的樣子

  • 如何理解這棵樹(shù)呢?

  • 我們看一個(gè)例子

表達(dá)式運(yùn)算

  • 如果給的表達(dá)式為 1 ?2 ?3

  • 結(jié)合序?yàn)橄聢D

  • 前兩個(gè)先結(jié)合

  • 得到的結(jié)果作為下一個(gè)運(yùn)算的左操作數(shù)

  • 然后和第3個(gè)結(jié)合

結(jié)合序

  • 如果把 第一個(gè)* 改成 + 號(hào)

  • 其他什么也沒(méi)加

  • 表達(dá)式是1 + 2 * 3

  • 后兩個(gè)會(huì)先結(jié)合

    • 得到的結(jié)果 作為下一個(gè)運(yùn)算的 右操作數(shù)

    • 然后再和1 進(jìn)行 加法運(yùn)算

  • 有了 語(yǔ)法樹(shù)

    • 下一步 要做什么呢?

  • 這棵語(yǔ)法樹(shù) 我們能看懂

    • 能執(zhí)行的 一條條字節(jié)碼指令

    • 但是cpu 需要的是

翻譯成 字節(jié)碼

  • 要把源程序 翻譯成字節(jié)碼 才能執(zhí)行

    • 字節(jié)碼 對(duì)應(yīng)著cpu的指令

  • 怎么把a(bǔ)st 轉(zhuǎn)化為字節(jié)碼(指令) 呢?

    • 需要 編譯(compile)

  • 從一種語(yǔ)言 到 另一種語(yǔ)言

    • compile

    • 從py文件

    • 到字節(jié)碼(指令)

    • 就是編譯

compile

  • 我可以看看這個(gè)編譯過(guò)程么?

指令

  • instruction

  • python3 -m dis Guido.py

    • -m 代表使用模塊

    • dis 代表反編譯(disassemble)

  • 我們可以看見(jiàn)

    • LOAD_NAME 裝載(函數(shù))名字

    • LOAD_CONST 裝載常量

    • CALL_FUNCTION 調(diào)用函數(shù)

    • POP_TOP 彈棧

    • 前面是行號(hào)

    • 每行對(duì)應(yīng)4條指令

編譯結(jié)果

  • 先看看這個(gè)pyc文件

    • 注意他在__pycache__文件夾下

  • :%!xxd

    • 把文件轉(zhuǎn)化為字節(jié)形態(tài)

  • 這純純的機(jī)器語(yǔ)言字節(jié)形態(tài)

    • 實(shí)在是看不懂啊??

    • 這真的是指令么?

  • 究竟什么是指令呢?

指令

  • py文件每行print 對(duì)應(yīng)4條指令

    • LOAD_NAME 裝載(函數(shù))名字

    • LOAD_CONST 裝載常量

    • CALL_FUNCTION 調(diào)用函數(shù)

    • POP_TOP 彈棧

  • https://github.com/python/cpython/blob/main/Lib/opcode.py

  • 這樣 我們 能否找到

    • 4條指令 分別對(duì)應(yīng)的 字節(jié)狀態(tài)值

找到對(duì)應(yīng)關(guān)系

指令助記符指令含義十進(jìn)制狀態(tài)十六進(jìn)制狀態(tài)LOAD_NAME裝載函數(shù)名稱1010x65LOAD_CONST裝載參數(shù)1000x64CALL_FUNCTION調(diào)用函數(shù)1420x8ePOP_TOP彈棧返回10x01

  • 可以找對(duì)應(yīng)關(guān)系

  • 我們從頭捋一下

python3 執(zhí)行過(guò)程

  • 不管是python3這個(gè)游樂(lè)場(chǎng)

    • 還是Guido.py這個(gè)python程序

    • 都在我們的硬盤(pán)上

  • 先得把文件從硬盤(pán)讀到內(nèi)存

python3 執(zhí)行的過(guò)程大致是這樣

  • 先把python3.8這個(gè)主解釋器

    • 加載到內(nèi)存中

  • 然后 在x86-64的cpu上 執(zhí)行

    • 模擬出 一臺(tái)python虛擬機(jī)

  • 準(zhǔn)備開(kāi)始 對(duì)py文件 解釋執(zhí)行

先編譯

  • 然后把參數(shù) Guido.py 這個(gè)需要執(zhí)行的程序 加載到內(nèi)存

    • 詞法分析 得到 詞流(token stream)

    • 語(yǔ)法分析 得到 抽象語(yǔ)法樹(shù)(Abstract Syntax Tree)

    • 編譯 得到 字節(jié)碼 (byte_code)

  • 也就是編譯后 的pyc文件

解釋執(zhí)行

  • 不過(guò) 這個(gè)pyc指令文件

    • 是基于python虛擬機(jī)的 虛擬cpu的 指令集的

  • 需要放到 模擬好的 python虛擬機(jī)中

  • 一條條指令 進(jìn)行執(zhí)行

換句話說(shuō)

  • 簡(jiǎn)化版的 hello.py 的執(zhí)行過(guò)程是:

    • 給了 python3 一個(gè)參數(shù) Guido.py

    • 使用 python3 這個(gè)解釋器來(lái)解釋執(zhí)行 Guido.py

    • Guido.py中的語(yǔ)句一句句地依次解釋執(zhí)行

  • 全解釋完成 后

    • 退出python這個(gè)程序

    • 把控制權(quán)交回到shell

  • 這些 都是基于 解釋器python3的

    • 先編譯成 python虛擬機(jī)的 虛擬指令字節(jié)碼

    • 然后用 python虛擬機(jī) 直接執(zhí)行虛擬指令

    • 所謂的 解釋器python3

  • 而解釋器(python3) 是

    • 在不同系統(tǒng) 不同架構(gòu)的cpu語(yǔ)言上 運(yùn)行的

  • 那不同的系統(tǒng)、cpu架構(gòu)

    • python3 為什么 都能正確地解釋?

總結(jié)

  • 這次把py源文件

    • 這里確立了優(yōu)先級(jí)

    • 詞法分析 得到 詞流(token stream)

    • 語(yǔ)法分析 得到 抽象語(yǔ)法樹(shù)(Abstract Syntax Tree)

    • 編譯 得到 字節(jié)碼 (bytecode)

  • 字節(jié)碼我們看不懂

    • 指令文件是基于python虛擬機(jī)的虛擬cpu的指令集

    • 所以反編譯 得到 指令文件(opcode)

  • 先從 python3最基礎(chǔ)的

    • python虛擬機(jī)是如何做的???

    • 變量聲明和賦值來(lái)看看

  • 我們下次再說(shuō)??

  • 藍(lán)橋->https://www.lanqiao.cn/courses/3584

  • github->https://github.com/overmind1980/oeasy-python-tutorial

  • gitee->https://gitee.com/overmind1980/oeasypython


[oeasy]python0135_python_語(yǔ)義分析_ast_抽象語(yǔ)法樹(shù)_abstract_syntax_tree的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
静海县| 扎鲁特旗| 南陵县| 青冈县| 荔波县| 齐河县| 云龙县| 屏边| 阜南县| 定陶县| 鲁甸县| 临清市| 蓝田县| 乌鲁木齐市| 宁南县| 武穴市| 新干县| 登封市| 平陆县| 济宁市| 井研县| 论坛| 宜章县| 永清县| 安化县| 翁牛特旗| 郸城县| 龙里县| 舒城县| 永定县| 乳山市| 卢湾区| 黔西县| 隆回县| 临泉县| 双柏县| 靖西县| 辽阳市| 金堂县| 当涂县| 甘孜|