在 Lisp 读取器宏中将输入读入字符串



我正在尝试制作一个将@this转换为"this"的阅读器宏。这是我目前拥有的:

(defun string-reader (stream char)
   (declare (ignore char))
   (format nil ""~a"" (read-line stream t nil t))   
)    
(set-macro-character #@ #'string-reader )

问题是这要求我在@this之后加上换行符。我也尝试过(读取),但这只返回尚未设置的变量测试。我不能只是硬编码@符号后面的字符数,因为我不知道会有多少。有什么办法可以解决这个问题吗?

编辑:这样做的唯一方法是遍历读取字符和躲猫猫字符,读取直到我到达 #),#\space 或 #\Newline?

您可以尝试使用 read,然后查看它返回的内容:

(defun string-reader (stream char)
   (declare (ignore char))
   (let ((this (let ((*readtable* (copy-readtable)))
                 (setf (readtable-case *readtable*) :preserve)
                 (read stream t nil t))))
     (etypecase this
       (string this)
       (symbol (symbol-name this)))))
(set-macro-character #@ #'string-reader)

上面将允许@This@"This",但不允许@333

此版本只读取一个字符串直到空格:

(defun read-as-string-until-whitespace (stream)
  (with-output-to-string (out-stream)
    (loop for next = (peek-char nil stream t nil t)
          until (member next '(#space #newline #tab))
          do (write-char (read-char stream t nil t) out-stream))))
(defun string-reader (stream char)
   (declare (ignore char))
   (read-as-string-until-whitespace stream))
(set-macro-character #@ #'string-reader)

例:

CL-USER 21 > @this
"this"
CL-USER 22 > @42
"42"
CL-USER 23 > @FooBar
"FooBar"

相关内容

  • 没有找到相关文章

最新更新