日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python实现解释器_Python 解释器初探

發布時間:2023/12/18 python 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python实现解释器_Python 解释器初探 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

A Python Interpreter Written in Python 是一篇很棒的文章,作者用 Python 實現了一個 Python 解釋器(Byterun),文章的前半部分講解 Python 解釋器的基本結構,實現一個玩具(簡易指令集)解釋器。

有時候我們把 Python 解釋執行的整個流程都叫做 Python 解釋器,它包含以下幾步:

lexer

parser

compiler

interpreter

以源碼文本作為輸入,1, 2, 3 步后得到 code object,并作為第 4 步的輸入,我們這里討論的解釋器只針對第 4 步。

可能需要說明的是,為什么 Python 作為解釋語言還有 compiler 呢,其實所謂解釋語言,只是在編譯步做相對(編譯語言,如 C,Java)少的工作。

從性質上說,Python 解釋器是一個 virtual machine,也是一個 bytecode interpreter。而 virtual machine 又可以分為基于棧(stack)的和基于寄存器(register)的,Python 解釋器屬于前者。

對于 Python 解釋器的輸入 code object,它是一個包含 bytecode 的對象,而 bytecode 是一組指令,是 Python 代碼的 IR。

以 7+5 為例,用一組玩具指令表示如下,其中 what_to_execute 就是 code object,instructions 就是 bytecode。

what_to_execute = {

"instructions": [

("LOAD_VALUE", 0), # the first number

("LOAD_VALUE", 1), # the second number

("ADD_TWO_VALUES", None),

("PRINT_ANSWER", None)

],

"numbers": [7, 5]

}

再加上變量的處理,就可以得到這個玩具 Python 解釋器了。

class Interpreter:

def __init__(self):

self.stack = []

self.environment = {}

def LOAD_VALUE(self, number):

self.stack.append(number)

def PRINT_ANSWER(self):

answer = self.stack.pop()

print(answer)

def ADD_TWO_VALUES(self):

first_num = self.stack.pop()

second_num = self.stack.pop()

total = first_num + second_num

self.stack.append(total)

def STORE_NAME(self, name):

val = self.stack.pop()

self.environment[name] = val

def LOAD_NAME(self, name):

val = self.environment[name]

self.stack.append(val)

def parse_argument(self, instruction, argument, what_to_execute):

""" Understand what the argument to each instruction means. """

numbers = ["LOAD_VALUE"]

names = ["LOAD_NAME", "STORE_NAME"]

if instruction in numbers:

argument = what_to_execute["numbers"][argument]

elif instruction in names:

argument = what_to_execute["names"][argument]

return argument

def run_code(self, what_to_execute):

instructions = what_to_execute["instructions"]

for each_step in instructions:

instruction, argument = each_step

argument = self.parse_argument(instruction, argument, what_to_execute)

if instruction == "LOAD_VALUE":

self.LOAD_VALUE(argument)

elif instruction == "ADD_TWO_VALUES":

self.ADD_TWO_VALUES()

elif instruction == "PRINT_ANSWER":

self.PRINT_ANSWER()

elif instruction == "STORE_NAME":

self.STORE_NAME(argument)

elif instruction == "LOAD_NAME":

self.LOAD_NAME(argument)

# better run_code making use of Python's dynamic method lookup

def execute(self, what_to_execute):

instructions = what_to_execute["instructions"]

for each_step in instructions:

instruction, argument = each_step

argument = self.parse_argument(instruction, argument, what_to_execute)

bytecode_method = getattr(self, instruction)

if argument is None:

bytecode_method()

else:

bytecode_method(argument)

what_to_execute = {

"instructions": [("LOAD_VALUE", 0),

("STORE_NAME", 0),

("LOAD_VALUE", 1),

("STORE_NAME", 1),

("LOAD_NAME", 0),

("LOAD_NAME", 1),

("ADD_TWO_VALUES", None),

("PRINT_ANSWER", None)],

"numbers": [1, 2],

"names": ["a", "b"]}

interpreter = Interpreter()

interpreter.run_code(what_to_execute)

在 Python 中對于一個函數對象 obj 我們可以使用 obj.__code__ 得到 code object,obj.__code__.co_code 得到 bytecode。但實際的輸出可能是不可讀的(字節),可以利用 Python dis 模塊(bytecode disassembler)中的 dis.opname(n) 得到字節對應的字符串,也可以直接用 dis.dis(obj) 輸出函數對象字節碼的解釋。

后半部分過度到真實的 Python bytecode,其中關于 frames 的部分非常值得一讀。

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的python实现解释器_Python 解释器初探的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。