lisp语法分析与执行分离

《sicp》4.1.7节读书笔记

这节中将书中之前实现的解释器做了改进,将语法分析于执行分离.这样做能提高很多效率,比如我们需定义一个过程,然后执行该过程多次.分情况说明:

1.语法分析于执行未分离

每次执行都会进行语法分析

2.语法分析于执行分离.

在定义该过程时,已经完成语法分析,该过程名保存在环境中的相应约束

就是,语法分析生成的(lambda (env) …).所以当执行该过程时,只需传入相应环境就可以完成执行,这就实现了一次分析,供永久执行.

实际例子:

输入语句

(define (f x) (+ x x))
(f 4)

分别分析以上两种情况的执行过程


//lisp解释器的语法分析和执行未分离的情况 输入: (define (f x) (+ x x)) ==> (eval ('define ('f 'x) ('+ 'x 'x)) env)
==> (eval-definition ('define ('f 'x) ('+ 'x 'x)) env )
==> (define-variable! (definition-variable ('define ('f 'x) ('+ 'x 'x)))
(eval (definition-value ('define ('f 'x) ('+ 'x 'x))) env)
env)
;其中的 (definition-variable ('define ('f 'x) ('+ 'x 'x)) ) 返回为 'f
(eval (definition-value ('define ('f 'x) ('+ 'x 'x))) env) 返回为 ('procedure ('x) ('+ 'x 'x) env)
//所以在这里执行完毕后 env环境中,多了一条f函数的约束.
('f ('procedure ('x) ('+ 'x 'x) env) env ) 输入: (f 4) ==> (eval ('f 4) env)
==> (apply (eval 'f env) 4)
;其中的(eval 'f env) 返回 ('procedure ('x) ('+ 'x 'x) env) ==>(apply ('procedure ('x) (+ 'x 'x) env) 4)
==>(eval-sequence ('+ 'x 'x) (('x:4) (env)) )
;其中(('x:4) (env)) 是执行(f 4)后创建的新环境
==>(eval ('+ 'x 'x) (('x:4) (env)))
==>(apply (eval '+ (('x:4) (env))) (4 4))
;其中(eval '+ (('x:4) (env))) 返回 ('primitive +) (假设初始环境含有 ""+"" 基本过程)
==>(apply ('primitive +) (4 4))
==>(apply-primitive-procedure ('primitive) (4 4)) ==>(apply-in-underlying-scheme
+ (4 4))
==>8
如果再输入一次(f 4)仍然将执行以上分析和执行过程,可见每执行次(f 4)解释器都将分析一次 f 函数,然后执行 //lisp解释器的语法分析与执行分开的情况 输入 (define (f x) (+ x x)) ==>(eval ('define ('f 'x) ('+ 'x 'x) begin_env)
==>((analyze ('define ('f 'x) ('+ 'x 'x))) begin_env)
;;;执行 (analyze ('define ('f 'x) ('+ 'x 'x)))
==>(analyze ('define ('f 'x) ('+ 'x 'x)) )
==>(analyze-definition ('define ('f 'x) ('+ 'x 'x)))
{
(let ((var 'f)
(vproc (analyze ('lambda ('x 'x) ('+ 'x 'x))))
(lambda (env)
(define-variable! var (vproc env) env)
'ok))
}
;;;执行 (vproc (analyze ('lambda ('x 'x) ('+ 'x 'x)))))
==>(analyze('lambda ('x 'x) ('+ 'x 'x)))
==>(analyze-lambda ('lambda ('x 'x) ('+ 'x 'x)))
{
(let ((vars ('x 'x))
( bproc (analyze-sequence ( ('+ 'x 'x)) )))
(lambda (env) (make-procedure ('x 'x) brpoc env)))
}
;;执行bproc
==>(analyze-sequence (('+ 'x 'x)))
==>{ (analyze ('+ 'x 'x))
(analyze-application ('+ x x)){
(let ((fproc (analyze '+))
(aprocs (map analyze ('x 'x))))
(lambda (env)
(execute-application (fproc env)
(map (lambda (aproc) (aproc env) aprocs))))
}
;执行(analyze '+)
==>(analyze-variable '+)
返回 :(lambda (env) (lookup-variable-value '+ env))
;执行(map analyze ('x 'x))
返回 :((lambda (env) (look-variable-value 'x env)) (lambda(env) (look-variable-value 'x env)))
返回:bproc:
(lambda(env)
(execute-application ((lambda (env) (lookup-variable-value '+ env)) env)
(map (lambda (aproc) (aproc env)) ((lambda (env) (look-variable-value 'x env)) (lambda(env) (look-variable-value 'x env))))
)) }}
==>返回:vproc=
(lambda (env) (make-procedure ('x 'x) brpoc env))
==>(make-procedure ('x 'x) brpoc env)
==>返回:('procedure ('x 'x) brpoc env)
==>返回:
(lambda(env)
(define-varibale! 'f) (vproc env) env)
;;代入 begin_env
==>((lambda(env) (define-varibale! 'f (vproc env) env) begin_env))
==>(define-varibale! 'f (vproc begin_env) begin_env)
==>(vproc begin_env)
f : ('procedure ('x 'x) brpoc begin_env)
最终:在 begin_env 中
f=('procedure
('x 'x)
(lambda(env)
(execute-application
((lambda (env) (lookup-variable-value '+ env)) env)
(map (lambda (aproc) (aproc env)) ((lambda (env) (look-variable-value 'x env)) (lambda(env) (look-variable-value 'x env))))))) //输入 (f 4)
==>(eval ('f 4) changed_env)
==>((analyze ('f 4)) changed_env)
==>(analyze-application ('f 4))
==>{
(let ( (fproc (lambda(env) (lookup-varible-value 'f env)))
(approcs (lambda(env) 4))
(lambda(env)
(execute-application (fproc env)
(map (lambda (aproc) (aproc env)) aproc)))))
}
==>代入changed_env
==> (execute-application (fproc changed_env) 4)
==> (execute-application
('procedure
('x 'x)
(lambda(env)
(execute-application
((lambda (env) (lookup-variable-value '+ env)) env)
(map (lambda (aproc) (aproc env)) ((lambda (env) (look-variable-value 'x env)) (lambda(env) (look-variable-value 'x env)))))))
4)
==>((lambda(env)
(execute-application
((lambda (env) (lookup-variable-value '+ env)) env)
(map (lambda (aproc) (aproc env)) ((lambda (env) (look-variable-value 'x env)) (lambda(env) (look-variable-value 'x env))))))) ('x:4 (begin_env)))
==>(execute-application ('primitive +) (4 4))
==>(apply-in-underlying-scheme
+ (4 4))
==>8

lisp语法分析与执行分离的更多相关文章

  1. 语法分析器初步学习——LISP语法分析

    语法分析器初步学习——LISP语法分析 本文参考自vczh的<如何手写语法分析器>. LISP的表达式是按照前缀的形式写的,比如(1+2)*(3+4)在LISP中会写成(*(+ 1 2)( ...

  2. Js引擎解析执行 阅读笔记

    Js引擎解析执行 阅读笔记 一篇阅读笔记 http://km.oa.com/group/2178/articles/show/145691?kmref=search&from_page=1&a ...

  3. 第1章列表处理——1.1 Lisp列表

    Lisp是啥? Lots of Isolated Silly Parentheses (大量分离的愚蠢的括号) Lisp指的是"LISt Processing"(列表处理),通过把 ...

  4. sqlserver 学习之分离与附加数据库

    在学习sqlserver数据库的过程中,我们会学习到有关一些听起来比较陌生的专用名词,比如说分离与附加这两个专有名词,对于我来说就是比较陌生的.好的,下面我们一起来学习一下吧.为了讲的通俗一点,下面以 ...

  5. [转帖]linux screen 命令详解,xshell关掉窗口或者断开连接,查看断开前执行的命令

    linux screen 命令详解,xshell关掉窗口或者断开连接,查看断开前执行的命令 https://binwaer.com/post/12.html yun install -y screen ...

  6. ORACLE数据库学习之体系结构

     Oracle体系结构 ORACLE数据库体系结构决定了oracle如何使用网络.磁盘和内存.包括实例(instance),文件(file)和进程(process不包括后台进程)三部分. 实例:每 ...

  7. ANTLR4权威指南 - 第7章 通过特定应用程序代码解耦语法

    第7章 通过特定应用程序代码解耦语法 到目前为止,我们已经知道了怎么用ANTLR的语法来定义语言了,接下来我们要给我们的语法注入一些新的元素了.就语法本身而言,其用处并不大,因为它只能告诉我们一个用户 ...

  8. Oracle 后台进程 详细说明

    一. 进程概述 先来看一下Oracle 11g 的架构图. 看起来比较模糊,我已经上传到了csdn 的下载. 是个pdf 文件, 2m 多. 那个看起来比较清楚. 也对每个进程做了解释. 下载地址:O ...

  9. Golang的演化历程

    本文来自Google的Golang语言设计者之一Rob Pike大神在GopherCon2014大会上的开幕主题演讲资料“Hello, Gophers!”.Rob大神在这次分 享中用了两个生动的例子讲 ...

随机推荐

  1. ABAP开发环境终于支持以驼峰命名法自动格式化ABAP变量名了

    Jerry进入SAP成都研究院前,一直是用C/C++开发,所以刚接触ABAP,对于她在某些语法环境下大小写敏感,某些环境下不敏感的特性很不适应.那时候Jerry深深地怀念之前在C/C++编程时遵循的驼 ...

  2. Protobuf的上手使用

    这里不赘述Json和Protobuf的比较和区别,只谈谈简单的使用 1.在Client-Server交互的过程中,都是以二进制数据传输,所以Json和Protobuf在使用的过程中,都存在序列化和反序 ...

  3. python selenium八大定位方法

    一.定位方法 注意:元素属性必须唯一存在 #id定位 find_element_by_id() #name定位 find_element_by_name() #class_name定位 find_el ...

  4. Computer Vision_33_SIFT: A novel point-matching algorithm based on fast sample consensus for image registration——2015

    此部分是计算机视觉部分,主要侧重在底层特征提取,视频分析,跟踪,目标检测和识别方面等方面.对于自己不太熟悉的领域比如摄像机标定和立体视觉,仅仅列出上google上引用次数比较多的文献.有一些刚刚出版的 ...

  5. android studio创建模拟器

    开发环境: 操作系统: windows10 教育版 1903 Android studio :  Android Studio 3.5.1Build #AI-191.8026.42.35.590020 ...

  6. Scrum会议博客以及测试报告(β阶段)

    3组Alpha冲刺阶段博客目录 一.Scrum Meeting1. [第十周会议记录](链接地址:https://www.cnblogs.com/Cherrison-Time/articles/120 ...

  7. Linux硬盘满了,系统速度贼慢,居然是Jenkins.log太大了

    用查找命令找出大于1G的文件 find / -size +1G -print 为什么jenkins.log会产生40+G的文件? 以上在Windows上的时候,运行了几个月,也没有发生这种现象? 而在 ...

  8. generator 和yeild

    参考 https://www.cnblogs.com/xybaby/p/6322376.html 使用yield那么该函数就变成了一个生成器方法. def zheng(n,m): if n<m: ...

  9. IDEA实用教程(九)—— 创建Servlet

    4. 创建Servlet 1) 第一步 2) 第二步 3) 第三步 4) 第四步 由于新创建的Web项目, 没有Tomcat环境, 所以创建的Servlet会发生导包错误,如下图所示 : 因此我们需要 ...

  10. 人脸识别调用返回http

    https://ai.baidu.com/docs#/Face-Detect-V3/top