Function READ, READ-PRESERVING-WHITESPACE

UP


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-whitespacereadと似ていますが、 印刷表現されたオブジェクトを区切っている どのような空白文字も保護します。 read-preserving-whitespaceは、 read-preserving-whitespace自身の引数recursive-ptrueのときは、 正確にreadのように動作します。

*read-suppress*falseのとき、 readは印刷表現として要求されている特定の区切り文字である 空白文字のときはそれを捨てます。 しかし、readは それが構文として意味を持つ場合は、 次の式の開始に使用できるようにするために、 その空白文字を保護します(unread-charで使用されます)。

もしシンボルか数のあとにすぐファイルの終わりが続いたとき、 readはそのシンボルか数の読み込みは成功します。 そして再び呼び出されたときにファイルの終わりが発生し、 ただeof-error-pに従い動作します。 もしファイルの終端に例えば空行やコメントなどの 無視できるテキストが含まれていたとき、 readはそれをオブジェクトの途中で終了したとはみなしません。

もしrecursive-ptrueの場合、 readの呼び出しは トップレベルからのものではなく、 それ自身がreadから呼び出されるような何らかの内部関数であるか、 あるいは似たような入力関数で構成されることが期待されます。

両関数はinput-streamから読み込んだオブジェクトを返却します。 もしeof-error-pfalseであり、 オブジェクトの開始より前にファイルの終わりに到達したときは、 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))

しかし、もしreadread-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はエラーを通知します。 これは、 readread-preserving-whitespaceが呼び出されるとき、 recursive-peof-error-pnilではなく、 あるオブジェクトの開始前にファイルの終わりに到達したときに 検出されます。

eof-error-ptrueのとき、 ファイルの終わりにて型end-of-fileのエラーが通知されます。

参考

peek-char, read-char, unread-char, read-from-string, read-delimited-list, parse-integer, 2. 構文, 23.1. リーダーの説明

備考

なし。


TOP, Github