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

最新文章

  1. 使用C#给Linux写Shell脚本
  2. Unit Test测试框架中的测试的执行顺序
  3. 狂屌的Windows下的定时任务工具xStarter
  4. windows 7 + vs2010 sp1编译 x64位版qt4
  5. more命令
  6. Jersey(1.19.1) - Use of @Context
  7. java rmi 使用方法
  8. PowerDesigner中在生成的数据库脚本中用name列替换comment列作为字段描述的方法
  9. 又是玻璃效果?调用一句代码就OK了
  10. Activity间传递数据
  11. Conccrent中 Unsafe类原理 以及 原子类AutomicXX的原理以及对Unsafe类的使用
  12. 在 Ubuntu14.04 上搭建 Spark 2.3.1(latest version)
  13. boost::filesystem经常使用使用方法具体解释
  14. nodejs web API 相关杂项
  15. 泡泡一分钟:A Multi-Position Joint Particle Filtering Method for Vehicle Localization in Urban Area
  16. 【dpdk】使用libpcap-PMD驱动收发包
  17. LeetCode: Convert Sorted Array to Binary Search Tree 解题报告
  18. jQuery单选组美化特效
  19. vue 文件中的注释
  20. Windows下的ROUGE文本测评工具基本安装

热门文章

  1. 阿里云SOP
  2. 部署python项目到linux服务器
  3. [dev][nginx] 在阅读nginx代码之前都需要准备什么
  4. Python中的列表推导式
  5. C++中string::find()函数和string::npos函数的使用
  6. Linux 中 /proc/kcore为啥如此之大
  7. Centos7安装nginx后提示“Welcome to nginx on Fedora!”,conf.d目录下无default.conf文件
  8. (java)selenium webdriver学习---三种等待时间方法:显式等待,隐式等待,强制等待
  9. 使用Jackson的@JsonFormat注解时出现少了 8 个小时
  10. 快速开平方取倒数的算法--嵌入式ARM转载