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

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

常量折叠是其中一种被很多现代编译器使用的编译器最优化技术。常量折叠是在编译时间简单化常量表达的一个过程。简单来说就是将常量表达式计算求值,并用求得的值来替换表达式,放入常量表。可以算作一种编译优化。

也就是我们最早举例子的时候说的,将2,3放入栈中,+ 进来的时候,2 3取出来进行运算,然后将运算结果放入栈中。

def constant_fold(code):
    while True:
        # 指令中找到两个连续的数字以及一个运算符
        for i, (a, b, op) in enumerate(zip(code, code[1:], code[2:])):
            if isinstance(a, int) and isinstance(b, int) and op in {"+", "-", "*", "/"}:
                m = Machine((a, b, op))
                m.run()
                code[i:i+3] = [m.top()]
                print("Constant-folded %s%s%s to %s" % (a, op, b, m.top()))
                break
        else:
            break
    return code

“读取-求值-输出”循环(英语:Read-Eval-Print Loop,简称REPL)是一个简单的,交互式的编程环境。这个词常常用于指代一个Lisp的交互式开发环境,但也能指代命令行的模式和例如APL、BASIC、Clojure、F#、Haskell、J、Julia、Perl、PHP、Prolog、Python、R、Ruby、Scala、Smalltalk、Standard ML、Tcl、Javascript这样的编程语言所拥有的类似的编程环境。这也被称做交互式顶层构件(interactive toplevel)。

read-eval-print loop

这个名字来自于以下几个Lisp用来实现这种机制的内置函数:

读入函数接收一个来自于用户的表达式,将其解析成数据结构并存入内存。例如,用户可能会输入一个s-表达式(+ 1 2 3),这句话会被解析成一个包含四个元素的链表。

求值函数负责处理内部的数据结构并对其求值。在Lisp中,求一个以函数名开头的s-表达式意味着对接下来的参数调用那个函数。所以函数"+"被在参数1 2 3上调用,产生结果6。

输出函数接受求值结果,并呈现将其给用户。尽管当前的结果“6”并不具有复杂的格式,但如果是一个较为复杂的表达式,那么它将会被精心处理,以便于更方便地被理解。

代码应当这样写:

def repl():
    print('Hit CTRL+D or type "exit" to quit.')

    while True:
        try:
            source = raw_input("> ")
            code = list(parse(source))
            code = constant_fold(code)
            Machine(code).run()
        except (RuntimeError, IndexError) as e:
            print("IndexError: %s" % e)
        except KeyboardInterrupt:
            print("\nKeyboardInterrupt")

这样,基本上的我们就完成了一个简单的解释器,实际上它的能力很弱小,但是作为一个锻炼思考的方式,是一个不错的实践。接下来,可以给这个解释器添加更多的功能。

另外,推荐几个其他的文章:

用 Python 从零开始写一个简单的解释器

一起来写个简单的解释器

如何使用Python编写一个Lisp解释器


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

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

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