首页
学习
活动
专区
圈层
工具
发布

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

,二是演示如何使用 Python 3 构造 Lisp 的一种方言 Schema,作者把自己的这个语言解释器称作 Lispy。...还有列表表达式:一个 "(" ,后面接零或多个表达式,后面再接一个 ")"。列表的第一个元素决定了其含义是什么: 以关键词作为开头的列表,如 (if ...)...,是一种特殊形式,含义取决于关键词是什么。 以非关键词开头的列表,如 (fn ...),是函数的调用。 Schema 的妙处在于整个语言体系仅需 5 个关键词和 8 种语法形式。...在本文中,我们会介绍 Schema 语言及其解释器的所有特点,但中间要经过两个步骤,先定义一个简单的语言,再定义 Schema 语言的全部内容。...在一个简单的解释器中,内部的表示形式是一个树形结构(一般被称为抽象语法树),反应了程序语句和表达式的嵌套结构。

1.6K40

Lisp的本质(The Nature of Lisp)学习思考

我许诺过会以一种全新的方式来解释Lisp, 我要重申我的许诺。但是我们此刻还没有到预定的地方, 所以还是先继续上边的讨论。...Lisp中函数的角色十分特殊, 函数也是一种数据类型, 就像整数和字符串一样, 因此可以把它赋值给符号。乘法函数Lisp的内置函数, 默认赋给*, 你可以把其他函数赋值给*, 那样*就不代表乘法了。...Lisp中的函数是一种数据类型, 和整数, 字符串, 符号等等一样。一个函数并不必然有一个名字, 这和C++或者Java语言的情形很不相同。在这里函数自己代表自己。...但是我们可以做的更好。我们先提一个问题, 怎样写一个工具, 通过查找目录结构中的源文件来自动生成Ant脚本。 用字符串处理的方式生成Ant脚本是一种简单的方式。...当然, 还有一种更加抽象, 表达能力更强, 扩展性更好的方式, 就是利用XML库在内存中直接生成XML节点, 这样的话内存中的节点就可以自动序列化成为字符串。

2.1K60
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    Clojure与LispClojure与Lisp

    域指定语言(Domain Specific Languages ) 不仅 简单,而且更一般化--lisp程序往往是按照 "自下而上" 的开发方式写成的....他的原意只是想做一种理论演算,用更简洁的方式定义图灵机。 所以,为什么上个世纪50年代的编程语言,到现在还没有过时?简单说,因为这种语言本质上不是一种技术,而是数学。数学是不会过时的。...2 函数也是一种数据类型 在Lisp语言中,函数与整数或字符串一样,也属于数据类型的一种。它有自己的字面表示形式(literal representation),能够储存在变量中,也能当作参数传递。...7 符号(symbol)类型 符号实际上是一种指针,指向储存在哈希表中的字符串。...如果你创造了一种新语言,其中有car、cdr、cons、quote、cond、atom、eq这样的功能,还有一种把函数写成列表的表示方法,那么在它们的基础上,你完全可以推导出Lisp语言的所有其他部分。

    2.4K30

    用JavaScript实现一个编译器

    现在前端开发中,我们常常会用到babel来编译例如react、vue框架的代码,以支持更多的(更古老的)浏览器,babel编译代码的过程就是编译原理的应用之一。...解析的过程中包含了两个关键步骤词法分析(Lexical Analysis)和语法分析(Syntactic Analysis),解析就是一个具象到抽象的过程。...2.1.1 词法分析 词法分析的过程,主要是将原代码(字符串),通过分词的方式生成一个具有描述程序语义的token列表。...分词的原理:逐个读取源代码中的字符,与预设的关键词、字符串、数字、操作符等LISP语言定义的语法相关规则,转换成 {type: 'xx', value: 'xx'} 的具有描述意义的形式 例如LISP:...(暂称作:tokens列表)按照顺序下来很好的描述了源代码中的字符串和编程语义。

    1.1K40

    有比JSON更好的东西吗?

    有两个轴线来比较各种语言: 自描述与模式定义的格式 可读格式与机器可读格式 即,是否在接收程序检查的单独文件(架构)中定义了结构的类型信息,或者消息本身是否包含类型信息。...无论是否以这种方式实现,HTTP / REST接口通常只是一种RPC协议。 ---- 人类可读的语言 JSON格式 http://json.org/ 我们都知道JSON,都同意它足够好。...优点: 用于配置架构和验证 简单易用 实际上对于写文档来说还不错 缺点: 一切都是字符串输入 没有实际的数组 复杂化,很冗长 大概有3-4种不同的方式来完成每一件事 仍然不是包含二进制数据的好方法 --...像许多Lisp解决方案一样,它非常有效,直到需要使两个Lisp实现使用同一类东西为止。至少从1970年代开始,就一直没有尝试过在Lisp之外流行。 没有实际的通用规范,更不用说实现了。...合理简单好看 缺点: 轻快的人会喜欢它,非轻快的人会讨厌它。 对于列表以外的复合数据类型,实际上没有公认的语法。

    5.3K30

    为什么Lisp语言如此先进?(译文)

    他的原意只是想做一种理论演算,用更简洁的方式定义图灵机。 所以,为什么上个世纪50年代的编程语言,到现在还没有过时?简单说,因为这种语言本质上不是一种技术,而是数学。数学是不会过时的。...在Lisp语言中,函数与整数或字符串一样,也属于数据类型的一种。它有自己的字面表示形式(literal representation),能够储存在变量中,也能当作参数传递。...符号实际上是一种指针,指向储存在哈希表中的字符串。所以,比较两个符号是否相等,只要看它们的指针是否一样就行了,不用逐个字符地比较。   8....如果你创造了一种新语言,其中有car、cdr、cons、quote、cond、atom、eq这样的功能,还有一种把函数写成列表的表示方法,那么在它们的基础上,你完全可以推导出Lisp语言的所有其他部分。...如果有多个函数,同时指向相同的变量,那么这种方法就会失效,但是在这个简单的例子中,它已经足够了。

    1.5K60

    :browser) 简单类型可不简单啊~)

    位于cljs.core/Keyword的关键字并不是仅仅如上述那样简单,其实一共有3种定义方式: 1.所见即所得 ;; 通过literal来定义 :i-am-a-keyword :i-am-a-namespace...原因十分简单但又难以理解——Lisp中代码即数据,数据即代码。作为Lisp的方言cljs自然传承了这一耀眼的特性!...由于symbol根据它在列表中的位置解析为Special Form或Var,为阻止这一过程需要通过quote函数来处理,而'就是quote的reader macro。...在clj/cljs中Var是一个容器,其内容为指向实际值的地址,当其内容为nil时称之为unbound,非nil时则称为bound。而一个Var可以对应1~N个Symbol。...;; Symbol a和b都对应同一个Var,这个Var指向1所在的内存地址 (def a 1) (def b 1) 这个和JAVA、C#中的String是一样的。

    81770

    用 Kotlin 的函数式编程 替代 GOF 设计模式用 Kotlin 的函数式编程 替代 GOF 设计模式函数式编程(FP)《Kotlin极简教程》正式上架:

    就像在OOP中,一切皆是对象,编程的是由对象交合创造的世界; 在FP中,一切皆是函数,编程的世界是由函数交合创造的世界。 函数式编程中最古老的例子莫过于1958年被创造出来的Lisp了。...Lisp由约翰·麦卡锡(John McCarthy,1927-2011)在1958年基于λ演算所创造,采用抽象数据列表与递归作符号演算来衍生人工智能。...他的项目需要用某种形式语言来编写语句,以记录关于世界的信息,而他感觉列表结构这种形式挺合适,既方便编写,也方便推演。于是就创造了LISP。...态射 态射指的是一种映射关系,简单理解,态射的作用就是把一个对象 A 里的值 a 映射为 另一个对象 B 里的值 b = f(a),这就是映射的概念。...对于给定的两个范畴 A 和 B, 函子的作用有两个: 将范畴 A 中的对象映射到范畴 B 中的对象。

    1.3K50

    NUS CS1101S:SICP JavaScript 描述:前言、序言和致谢

    然而,当我考虑特定的计算时,我经常对自己说:“我期望这个两个元素的列表是名字和姓氏,但我期望那个两个元素的列表是复数的实部和虚部,而我将把另一个两个元素的列表视为分数的分子和分母。”...自本书第一版写成以来,几乎已经有将近四十年的时间,许多组织数据的方式已经相对标准化,特别是“面向对象”的方法,许多语言,包括 JavaScript,都支持对象、字符串、堆和映射等专门的数据结构,并具有各种内置机制和库...它们并不都像 Iverson 为他的 APL 函数选择的那样简短和生动,但它们是以一种有意识和系统的方式选择的,以增强你对整体程序结构的理解。...Lisp 程序用功能膨胀的库,其效用超越了产生它们的应用程序。列表,Lisp 的本地数据结构,在很大程度上负责这种效用的增长。列表的简单结构和自然适用性反映在那些令人惊讶地非特异的函数中。...因此,解析技术在 Lisp 程序中几乎不起作用,语言处理器的构建很少成为大型 Lisp 系统增长和变化速度的障碍。最后,正是这种语法和语义的简单性造成了所有 Lisp 程序员所承担的负担和自由。

    34510

    Emacs Lisp

    中表示注释 ;; 在Elisp中做运算,调用函数的最简单的方式是 ;; (function arg1 arg2) ;; 这相当于通常的function(arg1,arg2),下面的表达式,对两个数字进行加法运算...函数对列表中的把列表中的每一个元素分别取出来,赋给hello函数 (mapcar 'hello list-of-names) ;; 重新定义greeting函数,在一个新的,清空的buffer中,对list-of-names...的开头 ;; 从头开始搜索字符串Hello,并且替换成Bonjour ;; 结束之后在把光标移会到一开始的buffer中。...'bold))) (other-window 1)) ;; 执行这个函数 (boldify-names) == 帮助和参考== ;; 在Emacs中我们可以通过如下的方式得到变量和函数的帮助信息...,在我按下 Ctrl-c Ctrl-` 的时候,会自动输出一个 markdown 的代码框,然后将光标定位到要输入代码的位置 ---- 总结 Lisp 真的很简洁优雅 只是括号看起来有点怪 它提供了编程的另一种思维方式

    2.8K40

    光剑评注:其实,说了这么多废话,无非就是: 一切皆是映射。不管是嵌套 XML,还是 Lisp 嵌套括号,还是 XXX 的 Map 数据结构,一切都是树形结构——映射。Lisp的本质(The Natur

    我们可以用很多种方式做到, 下面是其 中的一种, 十分简单: 以一种全新的方式来解释Lisp, 我要重申我的许 诺。但是我们此刻还没有到预定的地方, 所以还是先继续上边的讨论。...Lisp中函数的角色十分特殊, 函数也是一种数据 类型, 就像整数和字符串一样, 因此可以把它赋值给符号。...用字符串处理的方式生成Ant脚本是一种简单的方式。...当然, 还有一种更加抽象, 表达能 力更强, 扩展性更好的方式, 就是利用XML库在内存中直接生成XML节点, 这样的话内存中 的节点就可以自动序列化成为字符串。

    1.6K20

    Emacs Lisp

    中表示注释 ;; 在Elisp中做运算,调用函数的最简单的方式是 ;; (function arg1 arg2) ;; 这相当于通常的function(arg1,arg2),下面的表达式,对两个数字进行加法运算...函数对列表中的把列表中的每一个元素分别取出来,赋给hello函数 (mapcar 'hello list-of-names) ;; 重新定义greeting函数,在一个新的,清空的buffer中,对list-of-names...的开头 ;; 从头开始搜索字符串Hello,并且替换成Bonjour ;; 结束之后在把光标移会到一开始的buffer中。...'bold))) (other-window 1)) ;; 执行这个函数 (boldify-names) == 帮助和参考== ;; 在Emacs中我们可以通过如下的方式得到变量和函数的帮助信息...,在我按下 Ctrl-c Ctrl-` 的时候,会自动输出一个 markdown 的代码框,然后将光标定位到要输入代码的位置 ---- 总结 Lisp 真的很简洁优雅 只是括号看起来有点怪 它提供了编程的另一种思维方式

    2.6K30

    第5章 函数与函数式编程第5章 函数与函数式编程

    函数式编程不仅仅指的是Lisp、Haskell、 Scala等之类的语言,更重要的是一种编程思维,解决问题的思考方式,也称面向函数编程。 函数式编程的本质是函数的组合。...在函数式编程中,倾向于使用纯函数编程。正因为纯函数不会去修改数据,同时又使用不可变数据,所以程序不会去修改一个已经存在的数据结构,而是根据一定的映射逻辑创建一份新的数据。...我们有一个字符串列表 val strList = listOf("a", "ab", "abc", "abcd", "abcde", "abcdef", "abcdefg") 然后,我们想要过滤出字符串元素的长度是奇数的列表...通过上面的代码例子,我们可以看到,在Kotlin中,我们可以简单优雅的实现高阶函数。OK,现在逻辑已经实现完了,下面我们在 main 函数中运行测试一下效果。...在Kotlin中进行函数式编程相当简单自如。

    54410

    Emacs Lisp2

    ;; 为了实验本教程中的lisp命令,我们要让Emacs工作在lisp-interaction-mode工作模式下,;; 这个模式可以让我们在缓冲区中和Emacs进行互动,并且直接执行Lisp命令,得到结果...;; 在Elisp中做运算,调用函数的最简单的方式是;; (function arg1 arg2) ;; 这相当于通常的function(arg1,arg2),下面的表达式,对两个数字进行加法运算(+...);; 以后push函数可以在列表的头部插入新的元素,所以下面的命令将改变list-of-name中元素的个数(push "Stephanie" list-of-names);; mapcar函数对列表中的把列表中的每一个元素分别取出来...的开头;; 从头开始搜索字符串Hello,并且替换成Bonjour;; 结束之后在把光标移会到一开始的buffer中。...,在我按下 Ctrl-c Ctrl-` 的时候,会自动输出一个 markdown 的代码框,然后将光标定位到要输入代码的位置----总结Lisp 真的很简洁优雅只是括号看起来有点怪它提供了编程的另一种思维方式很值得花时间了解一下

    1.4K40

    Clojure 学习入门(18)—— 数据类型

    如何表示和处理数据 Clojure是一种动态类型语言,这意味着你在程序中永远不需要明确定义符号、函数、或者参数的数据类型。但是,所有的值仍然有一个类型。...用比率输入的常量将会自动简化。如果你输入4 / 2,将被简单的存储为2。 你能够以基数+r+值的形式输入任何整型常量。...they learn a new language" 在字符串中输入反斜杠字符,只需输入两个反斜杠。...如果这些数据类型中的任何一种都不足以表示某种数据结构,那么我们可以通过任何方式来组合它们。 这些数据类型都具有如下性质: 都不可变。...例如一个使用字符串的类似集合:(def languages-names #{"Java" "Lisp" "C++"}) 集合的实现方式跟映射十分类似。

    2.9K10

    位置与标识分离——入向流量优化

    LISP作为一种隧道技术,最为关键的就是EID对RLOC映射关系的学习。...第二种为Data-Probe方式,ITR通过发送探针数据包来触发目的EID所在ETR的Map-Reply。ITR会缓存Map-Reply中的映射信息,下一次碰到相同目的EID的包直接进行封装转发。...上述外层地址为目的主机EID,用于地址学习的包便可以在ALT网络中路由到ETR上了。 不过LISP-ALT这种方式有些复杂,一来要依赖于分布式的协议交互,二来还要维护ALT网络中EID的拓扑。...讲完了数据封装和控制平面,下面以Map-Request + LISP Map-Server Interface的学习方式为例,看一个LISP的具体转发实例。...近3年来LISP相关的IETF Draft非常多,其中绝大部分都是由Cisco推动的,可见LISP在Cisco未来的规划中是占据了一席之地的。

    1.3K70

    写给小白的开源编译器

    一、什么是编译器 从概念上简单讲: 编译器就是将“一种语言(通常为高级语言)”翻译为“另一种语言(通常为低级语言)”的程序。...很显然,二进制看上去并不好理解,而且编写二进制代码很麻烦,因此 CPU 架构支持把二进制操作映射作为一种更容易阅读的语言——汇编语言。...LISP 语言是一种超级简单的解析语法,并且很容易被翻译成其他语法,像这样: 所以到这里你应该知道我们要干什么了吧?那让我们再深入地了解一下具体要怎么进行“翻译”(编译)吧!...AST 是一个深度嵌套的对象,用一种更容易处理的方式代表了代码本身,也能给我们更多信息。...在 JavaScript 中 String 类的实例,是一个类数组,从下面这个例子可以看出来: 可能之前你会用 charAt 来获取字符串的单个字符,因为它是在 String 类型上的一个方法: 这两个方法都可以实现你想要的效果

    84410

    YAMLScript助YAML成为了适当的编程语言

    一个流序列可以写成方括号内用逗号分隔的列表: - [ Bob Marley, Peter Tosh, Bunny Wailer ] 或者!...${{ … }} Is Not YAML 但即使是经常使用的人也可以被原谅,他们会认为 YAML 是一种编程语言。 在基础设施管理软件中,YAML 数据经常被模板软件覆盖的执行代码所修饰。...VMware 的 Saltstack 以这种方式将 YAML 嵌入到其 Salt State 文件中,人们会认为编码就是在 YAML 中进行的,Müller 说,并用代码片段进行了演示。...Red Hat 的 Ansible 做了类似的事情,将 YAML 作为字符串嵌入到其配置代码中,Müller 观察到。 这两个自动化工具都使用 Jinja 模板来添加编码。...由于 Clojure 是一种函数式编程语言,基于 Lisp 语法 - "尽管它在语法上通常看起来不像是 Lisp",文档中指出 - 因此,从技术上讲,YAML 就是一种函数式编程语言(立即使其成为继 Microsoft

    25210

    简述babel解析过程

    月季的花期竟然这么长,五月都过完了,竟然还开着。 先要了解的概念 lisp-like function 和C-like function 如果对这两个概念不熟悉,这里有个简单的示例。...,虽然这个不是一个完整的LISP或C语法,它足以演示现代编译器的许多主要部分。...抽象语法树(AST),是一个嵌套很深的对象。它可以以一种既易于使用,又能告诉我们大量的代码信息。 例如:对于这个语法(add 2 (subtract 4 2))。...在转换的过程中,我们需要以深度优先的方式遍历这个抽象语法树的每个节点。...大部分时候代码生成仅仅是将抽象语法树转为字符串形式的代码进行返回。 代码生成器以几种不同的方式进行工作,有的会重复使用Tokens,有的会重新创建一个代码块儿。 当然,这中间有一个递归的过程。

    54620

    《Kotin 极简教程》第8章 函数式编程(FP)(1)第8章 函数式编程(FP)《Kotlin极简教程》正式上架:

    Lisp由约翰·麦卡锡(John McCarthy,1927-2011)在1958年基于λ演算所创造,采用抽象数据列表与递归作符号演算来衍生人工智能。...他的项目需要用某种形式语言来编写语句,以记录关于世界的信息,而他感觉列表结构这种形式挺合适,既方便编写,也方便推演。于是就创造了LISP。...态射 态射指的是一种映射关系,简单理解,态射的作用就是把一个对象 A 里的值 a 映射为 另一个对象 B 里的值 b = f(a),这就是映射的概念。...对于给定的两个范畴 A 和 B, 函子的作用有两个: 将范畴 A 中的对象映射到范畴 B 中的对象。...闭包包含以下两个组成部分: 要执行的代码块(由于自由变量被包含在代码块中,这些自由变量以及它们引用的对象没有被释放) 自由变量的作用域 在PHP、Scala、Scheme、Common Lisp、Smalltalk

    1.7K20
    领券