And*_*rew 10 lisp interpreter compilation clojure
我想知道Lisp程序的解释/编译过程中"读者"的目的,或者更确切地说是"读者"的任务.
从我刚刚完成的前期问题研究来看,在我看来,读者(在这种情况下特别是Clojure)可以被认为是"语法预处理器".它的主要职责是读者宏和原始形式的扩展.那么,有两个例子:
'cheese --> (quote cheese)
{"a" 1 "b" 2} --> (array-map "a" 1 "b" 2)
Run Code Online (Sandbox Code Playgroud)
因此,读者接受程序的文本(由S-Expressions组成),然后构建并返回可以直接评估的内存数据结构.
这与事实有多远(我是否过度简化了整个过程)?读者还有哪些其他任务?考虑到Lisps的优点是它们的同质性(代码作为数据),为什么需要词法分析(如果这确实可以与读者的工作相比)?
谢谢!
Rai*_*wig 20
通常,Lisp中的读取器读取s表达式并返回数据结构.READ是I/O操作:输入是字符流,输出是Lisp数据.
该打印机则正好相反:它需要Lisp的数据,并输出作为那些字符流.因此,它也可以将Lisp数据打印到外部s表达式.
请注意,解释意味着特定的东西:由解释器执行代码.但是许多Lisp系统(包括Clojure)都在使用编译器.计算Lisp表单值的任务通常称为评估.评估可以通过解释,汇编或两者的混合来实现.
S-Expression:符号表达式.外部的,文本的数据表示.外部意味着s表达式是您在文本文件,字符串等中看到的.因此,s表达式由某些(通常是外部的)中的字符组成.
Lisp数据结构:符号,列表,字符串,数字,字符,......
Reader:读取s表达式并返回Lisp数据结构.
请注意,s表达式也用于编码Lisp源代码.
在一些Lisp方言中,阅读器是可编程的和表驱动的(通过所谓的读表).该读表包含字符的读取器功能.例如,引号'字符绑定到一个函数,该函数读取表达式并返回(list'szotes表达式)的值.数字字符0..9绑定到读取数字的函数(实际上这可能更复杂,因为一些Lisps允许在不同的基数中读取数字).
S表达式为数据结构提供外部语法.
Lisp程序使用s表达式以外部形式编写.但并非所有的s表达式都是有效的Lisp程序:
(if a b c d e) is usually not a valid Lisp program
Run Code Online (Sandbox Code Playgroud)
Lisp的语法通常是在Lisp数据之上定义的.
IF具有以下语法(在Common Lisp中http://www.lispworks.com/documentation/HyperSpec/Body/s_if.htm):
if test-form then-form [else-form]
Run Code Online (Sandbox Code Playgroud)
所以它需要一个测试形式,一个then-form和一个可选的else-form.
作为s表达式,以下是有效的IF表达式:
(if (foo) 1 2)
(if (bar) (foo))
Run Code Online (Sandbox Code Playgroud)
但是由于Lisp程序是表单,我们也可以使用Lisp程序构造这些表单:
(list'if'(foo)1 2)是一个返回有效IF表单的Lisp程序.
CL-USER 24 > (describe (list 'if '(foo) 1 2))
(IF (FOO) 1 2) is a LIST
0 IF
1 (FOO)
2 1
3 2
Run Code Online (Sandbox Code Playgroud)
例如,可以使用EVAL执行该列表.EVAL需要列表形式 - 而不是s表达式.记住s表达式只是一个外部表示.要创建一个Lisp表单,我们需要阅读它.
这就是说代码是数据的原因.Lisp表单表示为内部Lisp数据结构:列表,符号,数字,字符串......在大多数其他编程语言中,代码是原始文本.在Lisp中,s表达式是原始文本.当使用READ函数读取时,s表达式将转换为数据.
因此,Lisp中的基本交互顶层称为REPL,Read Eval Print Loop.它是一个重复读取s表达式的LOOP,评估lisp表单并打印它:
READ : s-expression -> lisp data
EVAL : lisp form -> resulting lisp data
PRINT: lisp data -> s-expression
Run Code Online (Sandbox Code Playgroud)
所以最原始的REPL是:
(loop (print (eval (read))))
Run Code Online (Sandbox Code Playgroud)
因此,从概念的角度来看,为了回答你的问题,在评估期间,读者什么都不做.它不参与评估.评估由EVAL功能完成.通过调用READ调用读者.由于EVAL使用Lisp数据结构作为输入(而不是s表达式),因此读取器在Lisp表单被评估之前运行(例如通过解释或通过编译和执行它).
| 归档时间: |
|
| 查看次数: |
409 次 |
| 最近记录: |