Set-macro-character 有一个名为非终止-p 的可选参数。它似乎用于指示在读取宏字符后是否应该读取另一个字符,但reader algorithm似乎忽略了这个参数。是否将其设置为true或false是否有区别?
答案 0 :(得分:4)
如果您将non-terminating-p
设置为t
,则宏字符可以在符号名称中显示为非转义(例如符号#
中的foo#baz
)。如果您保留nil
并且读者在累积符号时遇到宏字符,则会终止符号的集合(如'
中的foo'bar
,其中显示为符号{{1} }和列表foo
)。
请参阅阅读器算法中的第8步 - 相关参数在被视为(quote bar)
和non-terminating macro character
之间切换宏字符。
答案 1 :(得分:2)
一个例子,你可以看到差异:
我们将使用两个不同的Unicode字符(这是使用LispWorks)。 当这些字符被用作符号的一部分时,它会变得有趣。
(defun single-quote-reader (stream char) ; just an example, it won't be called
(declare (ignore char))
(list 'quote (read stream t nil t)))
(set-macro-character #\℅ #'single-quote-reader t) ; non-terminating
(set-macro-character #\℆ #'single-quote-reader nil) ; terminating
(defun test ()
(list (read-from-string "foo℅bar") ; non-terminating
(read-from-string "foo℆bar"))) ; terminating
CL-USER 21 > (test)
(FOO\℅BAR ; non-terminating
FOO) ; terminating
答案 2 :(得分:1)
其他答案解释了行为并给出了示例,但我认为值得指出并链接到规范。 HyperSpec for set-macro-character描述了非终止-p 参数:
如果非终止-p为真,则char变为non-terminating宏字符;否则它变成terminating宏字符。
相关词汇表条目:
非终止 adj。 (宏的字符)当它出现在扩展令牌的中间时被视为组成字符。见Section 2.2 (Reader Algorithm)。
终止 n。 (宏字符)如果在解析令牌时出现,则终止该令牌。见Section 2.2 (Reader Algorithm)。
然后,正如m-n's answer所指出的,这是读者算法的第八步:
- 醇>
此时正在累积令牌,并且遇到偶数个多个转义字符。如果在文件末尾,则进入步骤10。否则,将读取字符y,并根据其语法类型执行以下操作之一:
如果y是成分或非终止宏字符:
- 如果y是带有大小写的字符,则可能会被相反大小写的相应字符替换,具体取决于当前可读表的可读大小写,如第23.1.2节(Lisp Reader中可读大小写的效果)所述)。
- Y附加到正在构建的令牌上。
- 重复步骤8。
...
如果y是终止宏字符,则它终止令牌。首先,字符y未读(参见unread-char),然后输入步骤10。