lisp语法分析与执行分离
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语法分析与执行分离的更多相关文章
- 语法分析器初步学习——LISP语法分析
语法分析器初步学习——LISP语法分析 本文参考自vczh的<如何手写语法分析器>. LISP的表达式是按照前缀的形式写的,比如(1+2)*(3+4)在LISP中会写成(*(+ 1 2)( ...
- Js引擎解析执行 阅读笔记
Js引擎解析执行 阅读笔记 一篇阅读笔记 http://km.oa.com/group/2178/articles/show/145691?kmref=search&from_page=1&a ...
- 第1章列表处理——1.1 Lisp列表
Lisp是啥? Lots of Isolated Silly Parentheses (大量分离的愚蠢的括号) Lisp指的是"LISt Processing"(列表处理),通过把 ...
- sqlserver 学习之分离与附加数据库
在学习sqlserver数据库的过程中,我们会学习到有关一些听起来比较陌生的专用名词,比如说分离与附加这两个专有名词,对于我来说就是比较陌生的.好的,下面我们一起来学习一下吧.为了讲的通俗一点,下面以 ...
- [转帖]linux screen 命令详解,xshell关掉窗口或者断开连接,查看断开前执行的命令
linux screen 命令详解,xshell关掉窗口或者断开连接,查看断开前执行的命令 https://binwaer.com/post/12.html yun install -y screen ...
- ORACLE数据库学习之体系结构
Oracle体系结构 ORACLE数据库体系结构决定了oracle如何使用网络.磁盘和内存.包括实例(instance),文件(file)和进程(process不包括后台进程)三部分. 实例:每 ...
- ANTLR4权威指南 - 第7章 通过特定应用程序代码解耦语法
第7章 通过特定应用程序代码解耦语法 到目前为止,我们已经知道了怎么用ANTLR的语法来定义语言了,接下来我们要给我们的语法注入一些新的元素了.就语法本身而言,其用处并不大,因为它只能告诉我们一个用户 ...
- Oracle 后台进程 详细说明
一. 进程概述 先来看一下Oracle 11g 的架构图. 看起来比较模糊,我已经上传到了csdn 的下载. 是个pdf 文件, 2m 多. 那个看起来比较清楚. 也对每个进程做了解释. 下载地址:O ...
- Golang的演化历程
本文来自Google的Golang语言设计者之一Rob Pike大神在GopherCon2014大会上的开幕主题演讲资料“Hello, Gophers!”.Rob大神在这次分 享中用了两个生动的例子讲 ...
随机推荐
- Go strconv模块:字符串和基本数据类型之间转换
本文转自Golove博客:http://www.cnblogs.com/golove/p/3262925.html ParseBool 将字符串转换为布尔值 // 它接受真值:1, t, T, TRU ...
- OC与swift混编 #import "项目名-Swift.h"失效问题
由于项目多个环境部署,每次改配置比较麻烦,所以线上环境一个TARGETS,内部环境一个TARGETS, 都知道oc和swift混编的时候,会生成一个'项目名-Swift.h'文件,这个文件是隐式的,需 ...
- 删除Ubuntu的UEFI启动项
bcdedit 删除 千万不要手贱用diskpart之类的命令直接删除文件夹,大写的没,有,用! 感谢这个视频的up主,youtube看不到请翻墙.https://www.youtube.com/wa ...
- net 与或非
&& op1 && op2 当op1和op2都是true时,返回true :如果op1的值是false,则不运算右边的操作数 || op1 || op2 当op1和op ...
- Linux之redis-cluster
一,为什么要用redis-cluster 1.并发问题 redis官方生成可以达到 10万/每秒,每秒执行10万条命令假如业务需要每秒100万的命令执行呢? 2.数据量太大 一台服务器内存正常是16~ ...
- 汽车电子测试项目管理系统-TPA
概述 INTEWORK-TPA(Test Project Administrator, 以下简称TPA) 是一款集成的测试项目管理工具,它可以管理测试过程中的所有数据,包括需求.用例.样件.计划.报告 ...
- 适用于在线服务的A/B测试方法论
适用于在线服务的A/B测试方法论 简介: 这篇文章旨在介绍适用于为在线服务进行A/B测试(A/B Test)的方法论.中文网络中目前还缺乏全面的入门级介绍. 我将首先讨论在线服务业进行A/B测试所考虑 ...
- Django之路——5 Django的模板层
你肯能已经注意到我们在例子视图中返回文本的方式有点特别. 也就是说,HTML被直接硬编码在 Python代码之中. def current_datetime(request): now = datet ...
- 题解 洛谷P2503 【[HAOI2006]均分数据】
看了眼题目和数据范围\(n \leq 20,k \leq 6\)自然想到了\(dfs\)分组求解,主要是被这道题坑自闭过. 然而硬来\(dfs\)肯定会被蜜汁\(T\)掉,因为暴力\(n\)个数所在集 ...
- SQL SERVER使用 CROSS APPLY 与 OUTER APPLY 连接查询
概述 CROSS APPLY 与 OUTER APPLY 可以做到: 左表一条关联右表多条记录时,我需要控制右表的某一条或多条记录跟左表匹配的情况. 有两张表:Student(学生表)和 S ...