如何反序列化s-exp然后将其封装并避免使用上限?

时间:2013-05-13 14:59:32

标签: lisp common-lisp s-expression

我应该阅读一个复杂的s表达式树,修改一些节点并将其保存在某个地方。

似乎在过程中'读取功能'正在“修改”输入。例如,在一个简单的例子中:

CL-USER> (read-from-string "(seq_num 123)")
(SEQ_NUM 123)
13

您可以看到它大写节点(以及值)。

同样看起来它可以将管道添加到值的最左侧和右侧。如:

CL-USER> (read-from-string "(password 000006013H)")
(PASSWORD |000006013H|)
21

它增加了管道!

有没有办法告诉'读不要这样做?当s-expression实际上是一个有效的LISP程序时,我猜这种修改是有充分理由的。但事实并非如此。让我们将该文件视为XML文件。一个看似是s-expr的简单配置文件。我不需要他“实习”它所读的符号。我只需要他将它作为一棵树进行反序列化,因为对我而言,这是搜索树的最简单方法('car和'cdr不太好)。

如果树形成了,那么每个符号都必须被实习。换句话说,我怎么能告诉他实习生没有符号,而是把它保持为字符串。 (因此它可以形成cons-tree,但它不是指向符号,而是指向字符串。你明白我的意思了吗?)

1 个答案:

答案 0 :(得分:4)

默认情况下,读者会内化符号。请注意,阅读器和打印机都会影响符号的使用和显示方式。如果您想查看符号调用(symbol-name some-symbol)的真实情况。如有必要,打印机将尝试转义符号,以便可以回读它并使用相同的案例。

CL-USER 26 > 'foo
FOO

CL-USER 27 > 'f\oo
|FoO|

CL-USER 28 > (symbol-name 'f\oo)
"FoO"

阅读器允许控制符号的读取方式。见下文。

要了解的一些事项:

  • 所有符号在内部默认为大写。默认情况下,阅读器大写小写字符。

  • 符号可以包含任意字符,包括小写字符。然后该符号需要使用转义符:

示例:

|This is a valid symbol.|

不是垂直条不是符号名称的一部分。它们用于逃避符号。另一个转义字符是反斜杠:

1\a2

上面也是一个符号。

  • 请注意,包含数字或字符的内容也可以是符号或数字,具体取决于读取基数:

示例:

00a

以上是读者群10中的符号。

相同的例子,其他阅读基础:

00a

以上是读者群16中的数字。

  • 非实习符号(不在包中)写成如下:

示例:

#:non-interned-symbol
  • 关键字符号:

示例:

:keyword-symbol

如何影响在阅读过程中创建/查找符号的情况?

  • 你可以逃避符号,见上文

  • 使用具有不同案例的可读表。

Common Lisp Hyperspec中的示例:23.1.2.1 Examples of Effect of Readtable Case on the Lisp Reader

关闭打印机中的转义

CL-USER 36 > (let ((*print-escape* nil))
               (write (read-from-string "(|passWord| 000006013H)")))
(passWord 000006013H)
...