首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在Lisp解释过程中,“读者”的任务是什么?

在Lisp解释过程中,“读者”的任务是什么?
EN

Stack Overflow用户
提问于 2010-12-27 17:43:17
回答 1查看 440关注 0票数 10

我想知道在解释/编译Lisp程序时“读者”的任务是什么,或者更准确地说,是什么。

从我刚刚做的预问题研究来看,在我看来,读者(在这种情况下特别是Clojure )可以被认为是一个“语法预处理器”。它的主要职责是扩展阅读器宏和原始形式。所以,有两个例子:

代码语言:javascript
运行
复制
'cheese         -->  (quote cheese)
{"a" 1 "b" 2}   -->  (array-map "a" 1 "b" 2)

因此,阅读器接收程序的文本(由S表达式组成),然后构建并返回可直接计算的内存中数据结构。

这离事实有多远(我是否过度简化了整个过程)?阅读器还执行哪些其他任务?考虑到Lisp的一个优点是它们的相似性(代码作为数据),为什么需要词法分析(如果这确实可以与读者的工作相媲美)?

谢谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2010-12-27 19:06:34

通常,Lisp中的读取器读取s表达式并返回数据结构。读取是一个I/O操作:输入是一个字符流,输出是Lisp数据。

打印机做了相反的事情:它获取Lisp数据并将其作为字符流输出。因此,它还可以将Lisp数据打印到外部s表达式。

请注意,解释意味着一些特定的东西:由解释器执行代码。但是许多Lisp系统(包括Clojure)都在使用编译器。为Lisp表单计算值的任务通常称为求值。评估可以通过解释、编译或两者的混合来实现。

S-Expression:符号表达式。数据的外部文本表示。外部表示s表达式是您在文本文件、字符串等中看到的表达式。因此,s表达式是由某些介质(通常是外部介质)上的字符组成的。

Lisp数据结构:符号,列表,字符串,数字,字符,...

Lisp :读取s表达式并返回数据结构。

请注意,s-expression也用于编码Lisp源代码。

在一些Lisp方言中,阅读器是可编程的,并且是表驱动的(通过所谓的读表)。此读取表包含字符的读取器函数。例如,'quote‘字符绑定到一个函数,该函数读取一个表达式并返回(list’quote expression)的值。数字字符0..9绑定到读取数字的函数(实际上,这可能更复杂,因为一些Lisp允许以不同的基数读取数字)。

S表达式提供了数据结构的外部语法。

Lisp程序是使用s表达式以外部形式编写的。但并非所有的s-expression都是有效的Lisp程序:

代码语言:javascript
运行
复制
(if a b c d e)   is usually not a valid Lisp program

Lisp的语法通常是在Lisp数据之上定义的。

IF具有例如以下语法(在Common Lisp http://www.lispworks.com/documentation/HyperSpec/Body/s_if.htm中):

代码语言:javascript
运行
复制
if test-form then-form [else-form]

所以它需要一个test-form,一个then-form和一个可选的else-form。

作为s表达式,以下IF表达式有效:

代码语言:javascript
运行
复制
(if (foo) 1 2)
(if (bar) (foo))

但是因为Lisp程序是表单,所以我们也可以使用Lisp程序构造这些表单:

(list 'if '(foo) 1 2)是一个返回有效IF表单的Lisp程序。

代码语言:javascript
运行
复制
CL-USER 24 > (describe (list 'if '(foo) 1 2))

(IF (FOO) 1 2) is a LIST
0      IF
1      (FOO)
2      1
3      2

例如,该列表可以通过EVAL执行。EVAL需要列表形式,而不是s-表达式。请记住,s表达式只是一种外部表示。要创建一个Lisp表单,我们需要读取它。

这就是为什么说代码就是数据。Lisp表单表示为内部Lisp数据结构:列表、符号、数字、字符串、...在大多数其他编程语言中,代码都是原始文本。在Lisp中,s-expression是原始文本。使用函数READ读取时,s表达式将转换为数据。

因此,Lisp中最顶层的基本交互称为REPL,即Eval Print Loop。它是一个循环,重复读取s表达式,计算lisp表单并打印出来:

代码语言:javascript
运行
复制
READ :  s-expression ->  lisp data
EVAL :  lisp form    ->  resulting lisp data
PRINT:  lisp data    ->  s-expression

所以最原始的REPL是:

代码语言:javascript
运行
复制
(loop (print (eval (read))))

因此,从概念的角度来看,为了回答你的问题,在评估过程中,读者什么也不做。它不参与评估。通过函数EVAL进行求值。读取器通过调用READ来调用。因为EVAL使用Lisp数据结构作为输入(而不是s表达式),所以阅读器在Lisp表单被计算之前运行(例如,通过解释或者通过编译和执行)。

票数 20
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4537793

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档