リーダ(reader)

リーダのグローバル変数は:

*read-base*
読み込時の基数;デフォルトは10
*readtable*
reader構文を決定するカレント読み込みテーブル

Readerのデフォルトマクロ文字は:


(   リスト読み込み 

" 文字列読み込み
' 引用符表現読み込み
# マクロ変換
; コメント
` back-quote
, list-time eval
@ 追加
% C言語表記の数式読み込み

エスケープ文字:



$ \backslash$   単一文字エスケープ

$ \vert...\vert$ 多重文字エスケープ

エスケープされていないsymbolが読まれると、 全ての構成される文字はデフォルトで大文字に変換され、 そして大文字のsymbolは内部に蓄えられる。 例えば、'abcと'ABCは同じsymbolとみなされる。 エスケープは、それらを区別するのに必要である。 '$ \vert$ABC$ \vert$, 'ABCと'abcは同一であるが、 '$ \vert$abc$ \vert$と'abcは違うsymbolである。 デフォルトとして、大文字のsymbolを入力したときでさえ、 そのsymbolを表示するときは EusLispのプリンタが内部の大文字表現から小文字に変換する。 この変換は、プリンタによって実行されている。 この変換は、 :UPCASE*print-case*に設定することにより、禁止される。

10.は整数の10として読まれ、実数の10.0ではない。 ':'がパッケージマーカーとして予約されているので、 '$ \vert g:pcube\vert$のようにsymbolを構成するものとして使うとき、エスケープ化しなければ ならない。 この制限は、文字':'の構文により強制されないが、 アルファベット順やletterの意味を決定する属性により強制される。 その文字の属性は、リーダから堅く結ばれる(hardwired)。 したがって、copy-readtableで新しいreadtableを作ったり、 set-syntax-from-charで文字のための構文的意味を組み直したりすることにより、 ある文字の構文を変更可能であるが、 その属性はどのようにしても変更することができない。 その一方で、数字はいつも数字であり、アルファベットはアルファベットで、 数値を表現するために'#$%@'の様な文字を使用することはできない。

%は、EusLispで拡張read-macro文字となっている。 挿入記述により書かれた数式の前に%を付けることにより、 その数式はlisp用の式に変換される。 具体例を上げると、 %(1 + 2 * 3 / 4.0)(+ 1 (/ (* 2 3) 4.0))に変換され、結果は2.5となる。 Cの様な関数呼出や行列参照も、lisp形式に変換される。 従って、%(sin(x) + a[1])(+ (sin x) (aref a 1))として評価される。 1つ以上の引数を持つ関数や2次元以上の行列は、 func(a b c ...)ary[1 2 3 ...]のように記述し、 func(a,b,c)ary[1][2][3]のように書かない。 相対表現や割り当てもまた、正しく扱われる。 それで、%(a $ <$ b)($ <$ a b)に変換され、 %(a[0] = b[0] * c[0])(setf (aref a 0) (* (aref b 0) (aref c 0)))として得られる。 単純な最適化は、重複した関数呼出や行列参照をなくすことである。 %(sin(x) + cos(x) / sin(x))(let* ((temp (sin x))) (+ temp (/ (cos x) temp)))のように変換される。

マクロ変換は#文字が前に付いている。 数値(integer)引数は、#とマクロ変換文字の間に与えられる。 これは、どの数字(0 .. 9)もマクロ変換文字として定義できないことを意味する。 リーダの標準のマクロ変換文字は次の通り:

#nA(..)
行列
#B
2進数
#D
[度]から[ラジアン]への変換; #D180 = 3.14
#F(...)
実数ベクトル
#nF((..))
実数行列; #2F((..) (..)) is matrix
#I(...)
整数ベクトル
#nI((...))
整数行列
#J(...)
一般オブジェクト #J(myclass ....); 古い定義
#O
8進数
#P
パス名
#R
[ラジアン]から[度]への変換; #R3.14 = 180.0
#S(classname slotname1 val1 slotname2 val2 ...)
構造体 (あらゆるオブジェクト)
#V(...)
ベクトル #V(vectorclass ...)
#X
16進数
#(...)
ベクトル
#n#
ラベル参照
#n=
ラベル定義
#'
関数; コンパイルコードあるいはlambda-closure
# $ \backslash$
文字
#,
読み込み時に評価
#+
条件読みだし(positive)
#-
条件読みだし(negative)
#*
ビットベクトル
#:
収容されてないsymbol
#$ \vert$...$ \vert$#
コメント; 入れ子可能

いくつかのリーダ関数は、eof-error-p, eof-valuerecursive-pのパラメータを持っている。 最初の2つのパラメータは、リーダがend-of-fileに出会ったときの動作を制御する。 eof-error-pのデフォルトは、Tである。これは、eof時のエラーの原因となる。 eofの発生を知りたかったり、snatch controlにシステムエラーを渡したくないなら、 eof-error-pにNILを指定すること。 それで、読み込みの最中にeofが現れたとき、リーダはエラーループに入る代りに eof-valueを返す。 eof-valueのデフォルトは、NILである。 そのため、実際にNILが読まれたのかeofが現れたのか判別できない。 それらを判別するためには、ストリームに決して現れない値を与えること。 そのような特殊データオブジェクトを作るには、consgensymを 使用すること。

recursive-pは、read-macro関数にしばしば使用される。 それは、リーダを再帰的に呼び出す。 recursive-pのnon-NIL値は、読み込み処理がどこかで始まっていて、 #n=#n#によってラベル付けされる書式の読み込みのために 内部テーブルを初期化 すべきでないことをリーダに告げている。



read &optional stream (eof-error-p t) (eof-value nil) recursive-p [関数]

s表現を1つ読み込む。


read-delimited-list delim-char &optional stream recursive-p [関数]

delim-charで終了するs表現を読み込む。 これは、コンマで区切られたリストや # $ \backslash$]のような特殊文字で終る数列を読むために役立つ。


read-line &optional stream (eof-error-p t) (eof-value nil) [関数]

# $ \backslash$newline(改行)で終了する1行を読み込む。 返された文字列には、最後の改行文字を含まない。


read-char &optional stream (eof-error-p t) (eof-value nil) [関数]

1文字読み込み、その整数表現を返す。


read-from-string string &optional (eof-error-p t) (eof-value nil) [関数]

stringからs表現を読み込む。 最初のs表現のみ読み込むことができる。 もし、複数のs表現を持つstringからの連続読み込み処理が必要であるならば、 make-string-input-streamで作られるstring-streamを用いること。


unread-char char &optional stream [関数]

streamcharを戻す。 1文字を越えて連続に戻すことはできない。


peek-char &optional stream (eof-error-p t) (eof-value nil) [関数]

streamから1文字を読み込むが、streamのバッファからその文字を削除しない。 これはread-charに続いてunread-charを実行したものと 同じである。


y-or-n-p &optional format-string &rest args [関数]

format-stringargsを画面に表示して、``yかnか''を尋ねる。 答えが``y''または``n''で始まらない場合、質問を繰り返す。 yならTそしてnならNILを返す。 それ以外は起こらない。


yes-or-no-p &optional stream [関数]

format-stringargsを画面に表示して、``yesかnoか''を尋ねる。 答えが``yes''または``no''でない場合、質問を繰り返す。 yesならTそしてnoならNILを返す。 それ以外は起こらない。


以下に示すreadtableの操作関数の中で、readtableのデフォルト値は グローバル変数*readtable*の値である。



readtable-p x [関数]

xがreadtableなら、Tを返す。


copy-readtable &optional from-readtable to-readtable [関数]
to-readtableが書かれていなければ、新しいreadtableを作る。 from-readtableのすべての情報がto-readtableに移される。 含まれる情報は、syntax table, read-macro tableと dispatch-macro tableでそれぞれ256個の要素を持つ。


set-syntax-from-char from-char to-char [from-readtable to-readtable] [関数]

from-readtableの中のfrom-charのsyntaxとread-macro定義を to-readtableの中のto-charにコピーする。


set-macro-character char func [non-teminating-p readtable] [関数]

charのread-macro関数としてfuncを定義する。


get-macro-character char [readtable] [関数]
charのread-macro関数を返す。


set-dispatch-macro-character dispchar char func [readtable] [関数]
dispcharcharの組み合せの dispatch read-macro関数としてfuncを定義する。


get-dispatch-macro-character dispchar char [readtable] [関数]
dispcharcharの組み合せの dispatch read-macro関数を返す。


2016-04-05