2015-06-19 99 views
2

我正在嘗試製作一個將@this轉換爲「this」的閱讀器宏。 這是我目前有:在Lisp閱讀器宏中讀取字符串輸入

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

的問題是,這要求我把一個換行符曾經@this後。我也嘗試過(讀取),但這只是返回未設置的變量測試。我不能硬編碼@符號後的字符數,因爲我不知道會有多少字符。有沒有什麼辦法解決這一問題?

編輯:是否只有這樣才能循環讀取char和peek-char,直到讀到#),#\ space或#\ Newline?

回答

3

你可以嘗試使用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" 
+0

是否可以允許它包括數字和冒號? – iHuman

+0

@iHuman第二個版本接受任何東西..例如'@; test =>「; test」'。 – Sylwester