set-macro-character的非终止-p参数有什么作用?

时间:2015-06-08 00:34:10

标签: macros common-lisp

Set-macro-character 有一个名为非终止-p 的可选参数。它似乎用于指示在读取宏字符后是否应该读取另一个字符,但reader algorithm似乎忽略了这个参数。是否将其设置为true或false是否有区别?

3 个答案:

答案 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所指出的,这是读者算法的第八步:

  
      
  1. 此时正在累积令牌,并且遇到偶数个多个转义字符。如果在文件末尾,则进入步骤10。否则,将读取字符y,并根据其语法类型执行以下操作之一:

         
        
    • 如果y是成分或非终止宏字符:

           
          
      • 如果y是带有大小写的字符,则可能会被相反大小写的相应字符替换,具体取决于当前可读表的可读大小写,如第23.1.2节(Lisp Reader中可读大小写的效果)所述)。
      •   
      • Y附加到正在构建的令牌上。
      •   
      • 重复步骤8。
      •   
    •   
    • ...

    •   
    • 如果y是终止宏字符,则它终止令牌。首先,字符y未读(参见unread-char),然后输入步骤10。

    •   
  2.