% Function READ, READ-PRESERVING-WHITESPACE
Function READ
, READ-PRESERVING-WHITESPACE
read
&optional
input-stream eof-error-p eof-value recursive-p
=> object
read-preserving-whitespace
&optional
input-stream eof-error-p eof-value recursive-p
=> object
input-stream - 入力ストリームの指定子
eof-error-p - generalized-boolean。デフォルトはtrue。
eof-value - オブジェクト。デフォルトはnil
。
recursive-p - generalized-boolean。デフォルトはfalse。
object - オブジェクト(Lispリーダーによって読み込まれたもの)か、eof-value
read
は、input-streamから
オブジェクトの印刷表現を構文解析し、
そのようなオブジェクトを構築します。
read-preserving-whitespace
はread
と似ていますが、
印刷表現されたオブジェクトを区切っている
どのような空白文字も保護します。
read-preserving-whitespace
は、
read-preserving-whitespace
自身の引数recursive-pがtrueのときは、
正確にread
のように動作します。
*read-suppress*
がfalseのとき、
read
は印刷表現として要求されている特定の区切り文字である
空白文字のときはそれを捨てます。
しかし、read
は
それが構文として意味を持つ場合は、
次の式の開始に使用できるようにするために、
その空白文字を保護します(unread-char
で使用されます)。
もしシンボルか数のあとにすぐファイルの終わりが続いたとき、
read
はそのシンボルか数の読み込みは成功します。
そして再び呼び出されたときにファイルの終わりが発生し、
ただeof-error-pに従い動作します。
もしファイルの終端に例えば空行やコメントなどの
無視できるテキストが含まれていたとき、
read
はそれをオブジェクトの途中で終了したとはみなしません。
もしrecursive-pがtrueの場合、
read
の呼び出しは
トップレベルからのものではなく、
それ自身がread
から呼び出されるような何らかの内部関数であるか、
あるいは似たような入力関数で構成されることが期待されます。
両関数はinput-streamから読み込んだオブジェクトを返却します。 もしeof-error-pがfalseであり、 オブジェクトの開始より前にファイルの終わりに到達したときは、 eof-valueが返却されます。
(read)
>> 'a
=> (QUOTE A)
(with-input-from-string (is " ") (read is nil 'the-end)) => THE-END
(defun skip-then-read-char (s c n)
(if (char= c #\{) (read s t nil t) (read-preserving-whitespace s))
(read-char-no-hang s)) => SKIP-THEN-READ-CHAR
(let ((*readtable* (copy-readtable nil)))
(set-dispatch-macro-character #\# #\{ #'skip-then-read-char)
(set-dispatch-macro-character #\# #\} #'skip-then-read-char)
(with-input-from-string (is "#{123 x #}123 y")
(format t "~S ~S" (read is) (read is)))) => #\x, #\Space, NIL
例として、次のリーダーマクロの定義を考えます。
(defun slash-reader (stream char)
(declare (ignore char))
`(path . ,(loop for dir = (read-preserving-whitespace stream t nil t)
then (progn (read-char stream t nil t)
(read-preserving-whitespace stream t nil t))
collect dir
while (eql (peek-char nil stream nil nil t) #\/))))
(set-macro-character #\/ #'slash-reader)
ここで、次の式に対してread
を呼び出すことを考えます。
(zyedh /usr/games/zork /usr/games/boggle)
マクロ/
は、複数の/
文字によって分割されたオブジェクトを読み込むので、
/usr/games/zork
は、(path usr games zork)
のように読み込まれます。
したがって例の全体の式は、次のように読み込まれます。
(zyedh (path usr games zork) (path usr games boggle))
しかし、もしread
が
read-preserving-whitespace
の代わりに使用されたとき、
シンボルzork
を読み込んだ後に続く空白は切り捨てられます。
次にpeek-char
が呼ばれたときは続く/
を見るので、
繰り返しは継続し、次のように解釈されます。
(zyedh (path usr games zork usr games boggle))
これは空白が切り捨てられたときのものです。 もしインタープリターのコマンドが単一の文字のコマンドを受け取り さらなるオブジェクトの読み込みがあるとき、 シンボルの後の空白文字を切り捨てないときは、 そのシンボルが読み込まれた後にコマンドが解釈されるかもしれません。
*standard-input*
,
*terminal-io*
,
*readtable*
,
*read-default-float-format*
,
*read-base*
,
*read-suppress*
,
*package*
,
*read-eval*
read
は、オブジェクトの表現の最中にファイルが終わったときは、
eof-error-pに関係なく型end-of-file
のエラーが通知されます。
例えば、あるファイルから読み込まれるオブジェクト内ににおいて、
左かっこに対応するはずの十分な右かっこが含まれていなかったときは、
read
はエラーを通知します。
これは、
read
かread-preserving-whitespace
が呼び出されるとき、
recursive-pとeof-error-pがnil
ではなく、
あるオブジェクトの開始前にファイルの終わりに到達したときに
検出されます。
eof-error-pがtrueのとき、
ファイルの終わりにて型end-of-file
のエラーが通知されます。
peek-char
,
read-char
,
unread-char
,
read-from-string
,
read-delimited-list
,
parse-integer
,
2. 構文,
23.1. リーダーの説明
なし。