热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Lisp解释器的实现

2019独角兽企业重金招聘Python工程师标准解释器是一种复杂有用的工具,用到了很多技能。由于Lisp简单优雅的设计,让Lisp解释器的设计成为

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

解释器是一种复杂有用的工具,用到了很多技能。

由于 Lisp 简单优雅的设计,让 Lisp 解释器的设计成为一种每个程序员都有能力尝试的挑战。

没有复杂的形式化语法。解释器的每一个部分都向程序员开放,代码和数据结构的统一,读取期,编译期和运行期的分离,让这门语言的扩展能力无以伦比,达到了理论上能想象的任何程度。

读取期

只有几个字符的读取会产生不同的状态。括号,空格,单引号,双引号,反引号,井号,分号,反斜杠,逗号,冒号。

( 左括号标志一个列表的开始,) 右括号标志一个列表的结束。

(setq var 10)

空格分离两个不同的语言单位,可以是字符串,也可以数字,符号,keyword 等

(if nil 1 0)

单引号是 (quote xx) 的缩写,算是一个语法上的简写。

'(1 2 3) == (quote 1 2 3) == (list 1 2 3)

双引号开始一个字符串,也结束一个字符串。

(print "hello world!")

反引号是另外一种 (quote xx) 的缩写,其中的一些符号会有特别的意义,例如逗号代表一个列表模板中的变量插入,,@(逗号加小老鼠)代表对一个内插列表的展开。

`(print ,var ,@list 10)

井号(或问号)通常开始一个字符,或一个特别的数据结构,例如多维数组或一个函数的解引用。

#\a #2(1 2 3)

冒号开始一个关键字,这个关键字类似 Ruby 的符号,是一种自身求值的字符串表示方法而已,用于做函数参数的键指示,是一种在数据结构上快速的字符串实现。

(defun (:from x :end y) (print '(x y))

反斜杠通常对后面的字符串进行转义,代表一些特别的字符,

分号是注释的开始标记,到每行的结束,除了 Scheme,没有多行注释的起始标记,需要每行都进行注释标记。

;; This is comments

还有一些符号,是在进入一个状态后才会有效。

最多的就是字符串,进入字符串模式后,有格式化标记,%(emacs lisp), ~ (common lisp). 还有转义标记 \ 来表示不能打印或显示的字符。在 Common Lisp 中,井号之后的反斜杠代表一个字符的开始。还有关于正则表达式一些特别字符的标记,和字符串是不同的。在不同的上下文中。正则表达式和字符串是不同的类型,虽然语法相同,都是用双引号界定的。

(format t "%times" time)

进入符号定义后,允许的字符是很多的,通常用一些字符做后缀来表示一些特定的命名规则,例如叹号结尾表示有副作用,问号结尾表示返回一个真假值。

(symbol? var) => t
(set! var 10)

读取到的数据结构可以是嵌套的。所有的数据类型都是动态的,用一个符号表示。

只有一种或两种数据结构,就是列表或向量,也可以抽象成一个序列。

同时建立了好几个数据结构,来维护生成的代表代码的树形数据结构。

  1. 数字表,所有的数字,都用一个数字 ID 来表示一个数字。

  2. 关键字表,这个表是全局共享的,键和值内容相同。

  3. 符号表,每个符号都用 name 映射一个字符串名字,用 value 映射一个值,这个值可能是一个数据结构, plist 映射一个属性表,是一个嵌套的查询表,也是用字符串做键,用一个对象或原子类型做值。函数也可能是一个单独的键来定义,也可能定义在 value 中。

  4. 保存局部变量的一个符号表列表,不同深度的列表,有不同的局部符号表。

编译期:

扫描数据结构中每个列表的第一个符号,判断是否是一个用 defmacro 定义的宏,如果是,就按照定义的规则,将这个列表进行转换,并替换掉原来的数据结构。这个扫描是反复进行的,直到找不到符合条件的宏的定义。

运行期

递归的,深度优先的对列表或符号进行解释,自身求值的返回自身,列表结构就把第一个符号当成函数名称,后面的当成参数,进行运算。返回计算的值或是一个数据结构。

在读取期,一些实现允许对读取的规则进行动态定义,改变一些字符的含义,是读取期的读取期。

在编译期和运行期,宏或函数都可能会返回值或返回一个数据结构,而这个数据结构,就会替换掉原来的表达式,成为新的将要计算的表达式。尤其编译期的这种扩展,可以任意改变数据结构,在文法上对代码进行扩展,实现一定范围甚至是全局的代码变更和重写,将抽象实现到代码的形式上,实现文法和算法的多重转换。

许多自称是 Lisp 方言的语言,在这点上,由于太多分化的语法,很难将代码表现成一种和数据统一的数据结构,从而实现对代码的重写成为泡影。所以,在语法上追求的各种不同的形式,将会让解析后的数据结构丧失重写代码的能力,算是一个平衡吧。

Lisp 虽然在很多表现形式上笨拙,难看,但他的这种扩展性让他有能力担当任何形式的抽象语言的进化和表示。成为永不过时的语言。


转:https://my.oschina.net/u/563463/blog/164250



推荐阅读
  • 如何用UE4制作2D游戏文档——计算篇
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了如何用UE4制作2D游戏文档——计算篇相关的知识,希望对你有一定的参考价值。 ... [详细]
  • 本文介绍了计算机网络的定义和通信流程,包括客户端编译文件、二进制转换、三层路由设备等。同时,还介绍了计算机网络中常用的关键词,如MAC地址和IP地址。 ... [详细]
  • Go GUIlxn/walk 学习3.菜单栏和工具栏的具体实现
    本文介绍了使用Go语言的GUI库lxn/walk实现菜单栏和工具栏的具体方法,包括消息窗口的产生、文件放置动作响应和提示框的应用。部分代码来自上一篇博客和lxn/walk官方示例。文章提供了学习GUI开发的实际案例和代码示例。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 本文详细介绍了PHP中与URL处理相关的三个函数:http_build_query、parse_str和查询字符串的解析。通过示例和语法说明,讲解了这些函数的使用方法和作用,帮助读者更好地理解和应用。 ... [详细]
  • C语言注释工具及快捷键,删除C语言注释工具的实现思路
    本文介绍了C语言中注释的两种方式以及注释的作用,提供了删除C语言注释的工具实现思路,并分享了C语言中注释的快捷键操作方法。 ... [详细]
  • baresip android编译、运行教程1语音通话
    本文介绍了如何在安卓平台上编译和运行baresip android,包括下载相关的sdk和ndk,修改ndk路径和输出目录,以及创建一个c++的安卓工程并将目录考到cpp下。详细步骤可参考给出的链接和文档。 ... [详细]
  • Java String与StringBuffer的区别及其应用场景
    本文主要介绍了Java中String和StringBuffer的区别,String是不可变的,而StringBuffer是可变的。StringBuffer在进行字符串处理时不生成新的对象,内存使用上要优于String类。因此,在需要频繁对字符串进行修改的情况下,使用StringBuffer更加适合。同时,文章还介绍了String和StringBuffer的应用场景。 ... [详细]
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
  • 闭包一直是Java社区中争论不断的话题,很多语言都支持闭包这个语言特性,闭包定义了一个依赖于外部环境的自由变量的函数,这个函数能够访问外部环境的变量。本文以JavaScript的一个闭包为例,介绍了闭包的定义和特性。 ... [详细]
  • Android源码深入理解JNI技术的概述和应用
    本文介绍了Android源码中的JNI技术,包括概述和应用。JNI是Java Native Interface的缩写,是一种技术,可以实现Java程序调用Native语言写的函数,以及Native程序调用Java层的函数。在Android平台上,JNI充当了连接Java世界和Native世界的桥梁。本文通过分析Android源码中的相关文件和位置,深入探讨了JNI技术在Android开发中的重要性和应用场景。 ... [详细]
  • 先看官方文档TheJavaTutorialshavebeenwrittenforJDK8.Examplesandpracticesdescribedinthispagedontta ... [详细]
  • Python爬虫中使用正则表达式的方法和注意事项
    本文介绍了在Python爬虫中使用正则表达式的方法和注意事项。首先解释了爬虫的四个主要步骤,并强调了正则表达式在数据处理中的重要性。然后详细介绍了正则表达式的概念和用法,包括检索、替换和过滤文本的功能。同时提到了re模块是Python内置的用于处理正则表达式的模块,并给出了使用正则表达式时需要注意的特殊字符转义和原始字符串的用法。通过本文的学习,读者可以掌握在Python爬虫中使用正则表达式的技巧和方法。 ... [详细]
  • 这篇文章主要介绍了Python拼接字符串的七种方式,包括使用%、format()、join()、f-string等方法。每种方法都有其特点和限制,通过本文的介绍可以帮助读者更好地理解和运用字符串拼接的技巧。 ... [详细]
  • MySQL中的MVVC多版本并发控制机制的应用及实现
    本文介绍了MySQL中MVCC的应用及实现机制。MVCC是一种提高并发性能的技术,通过对事务内读取的内存进行处理,避免写操作堵塞读操作的并发问题。与其他数据库系统的MVCC实现机制不尽相同,MySQL的MVCC是在undolog中实现的。通过undolog可以找回数据的历史版本,提供给用户读取或在回滚时覆盖数据页上的数据。MySQL的大多数事务型存储引擎都实现了MVCC,但各自的实现机制有所不同。 ... [详细]
author-avatar
林小秋
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有