c++ 解释器模式_动态编译与解释器模式_解释器模式用处(2)

电脑杂谈  发布时间:2017-02-23 10:43:18  来源:网络整理

正如『正义的花生』在数学与编程中提到的一样:

普通程序员使用的编程语言,就算是C++这样毛病众多的语言,其实也已经比数学家使用的语言好很多。用数学的语言可以写出含糊复杂的证明,在期刊或者学术会议上蒙混过关,用程序语言写出来的代码却无法混过计算机这道严格的关卡。因为计算机不是人,它不会迷迷糊糊的点点头让你混过去,或者因为你是大师就不懂装懂。代码是需要经过现实的检验的。如果你的代码有问题,它迟早会导致出问题。

诚然,大牛作者在思想上有很多偏执的地方,但是往往他的观点我都有着不小的认同感。前边那篇『怎样写一个解释器』也是他的文章。

所以,学习写一个解释器,可以带给我更多的思考,从效率,空间,机器等等方面进一步认识程序运行的本质,将这种认识正反馈到实际编程中,将潜移默化的带来影响。当然,这篇文章试着依葫芦画瓢的写完一个解释器,显然仅仅算是摸了摸门道,想要继续探索,还有更多的事情可以做。做更多的事情,可以参考上边提到的开源项目Crianza。

堆栈机的执行原理很简单,将需要处理的值放进堆栈中,然后执行。Python, Java这些高级语言将它作为自己的虚拟机。

所以我们利用了堆栈的方式存放指令。首先,我们需要一个指令指针栈,它能够储存返回地址。这个返回地址就是当我们执行一个子程序(如函数)的时候,需要用它跳回到开始调用该函数的地方。

我们将这个复杂的问题简洁化。比如有一个数学表达式:(2+3)*4 ,这个表达式的意思就是依次推入2 3 + 4 *, 将2 和3 依次推入栈中,接下来要推入的指令是 +, 将两个数字弹出,令他们执行加法运算,然后将结果入栈。然后继续进行下去,直到计算出结果。

依靠这个原理,我们开始建立一个栈,我们使用python 中的一个类 collections.deque。

from collections import deque
class Stack(deque): # 定义一个栈
    push = deque.append  # 添加元素
    # 返回最后一个元素
    def top(self):
        return self[-1]

deque 中自带pop 方法,所以我们就不用再定义 pop .

接下来我们继续构建一个虚拟机的类 Machine。 我们需要两个栈和一段储存代码的内存空间。一个栈储存数据,一个栈储存地址。得益于Python 动态类型,因此我们可以往列表里面存储任何东西,但是我们不能区分列表里面的内置函数和字符串,正确的做法是将Python 内置函数单独存放在一个列表。这里我们使用字典方法,键值分别对应字符串和函数。另外,我们需要一个指令指针,用来指向代码中下一个需要被执行的模块。

class Machine:
    def __init__(self, code): # 预先定义一个初始化函数
       self.data_stack = Stack()
       self.return_addr_stack = Stack()
       self.code = code
       self.instruction_pointer = 0 
    # 再创建一些栈结构中必备的函数
    def pop(self):
        return self.data_stack.pop()
    def push(self, value):
        self.data_stack.push(value)
    def top(self):
        return self.data_stack.top()


本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/jisuanjixue/article-34020-2.html

相关阅读
    发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

    热点图片
    拼命载入中...