Skip to content

Instantly share code, notes, and snippets.

@haruo-wakakusa
Last active September 8, 2018 09:36
Show Gist options
  • Save haruo-wakakusa/aac241ca8fab810bae81ea25610377f7 to your computer and use it in GitHub Desktop.
Save haruo-wakakusa/aac241ca8fab810bae81ea25610377f7 to your computer and use it in GitHub Desktop.
HyperSpec「2.2 Reader Algorithm」の私訳

注意書き

この訳はただのメモ書きであり、原著作者に許可を得て公開しているものではありません。

2.2節 リーダーアルゴリズム

この節では入力文字ストリームからオブジェクトをパースするためのLispリーダーで使われるアルゴリズムを記述する。 Lispリーダーがマクロ文字をどのように処理するかということ含めて解説する。

トークンを扱う時、リーダーの基本的な機能はシンボル表現と数値表現を見分けることである。トークンが集約された時、 [表2-9]における数値型の文法を満たすならば数値を表しているものとする。もしそれが数値でなかった場合、 潜在的な数値(potential number)の文法を満たすならば潜在的な数値であるものとする。 トークンが数値あるいは潜在的な数値のいずれかでないならば、それはシンボルを表すものとする。

Lispリーダーのアルゴリズムは次のようなものである:

  1. ファイルの終端であれば、[read]シンボルの仕様に従って処理される。 ファイルの終端でなければ、文字 x が入力ストリームから読み込まれ、 x の文字文法型(character syntax type)に基づいてステップ2〜7のどれかに送出される。

  2. x が不正な文字(invalid character)であるならば、reader-error型のエラーが通知される。

  3. x が空白文字(whitespace[2] character)であるならば、 x を捨ててステップ1に戻る。

  4. x が終端マクロ文字(terminating macro character)または 非終端マクロ文字(non-terminating macro character)である場合は それと関連した2つの引数(入力ストリーム, x)を取るリーダーマクロ関数が呼び出される。

  • リーダーマクロ関数はその内部で入力ストリームから必要なだけ文字を読み込む場合がある。 その場合は、マクロ文字のすぐ後ろの文字列がそのマクロに従うことになる。 Lispリーダーはリーダーマクロ関数を再帰的に呼び出す場合がある。

  • リーダーマクロ関数は入力ストリーム以外に副作用を及ぼしてはならない。 [read]操作のバックトラックとリスタートによって、 x が一度だけ表れる式を1つリードする間に Lispリーダーのフロントエンド(例えばエディタや継続不可能なエラーハンドラなど)が リーダーマクロ関数を繰り返し呼び出すことを防ぐためである。

  • リーダーマクロ関数は値を0個または1個返す。 値を1個返す場合は、その値はread操作の結果として返され、アルゴリズムが完了する。 値を0個返す場合は、ステップ1に戻る。

  1. x が単一エスケープ文字(single escape character)である場合、 その次の文字 y が読み出される。x の次がファイルの終わりである場合は end-of-file 型の エラーが送出される。y は構成特性(constituent trait)がアルファベティック(alphabetic[2])な 場合に限って、1つの構成(constituent)として扱われる。 y はトークンを開始するために使われ、ステップ8に進む。

  2. x が複数エスケープ文字(multiple escape character)である場合、 トークン(トークン開始時は文字を保持しない)が開始され、ステップ9に進む。

  3. x が構成文字(constituent character)である場合、トークンを開始する。 トークンが読み込まれた後、そのトークンはLispオブジェクトとして解釈されるか 不正な文法と解釈されるかのいずれかである。 トークンがオブジェクトを表す場合はそれがread操作の結果として返される。 トークンが不正な文法である場合はエラーが送出される。 x がケース(case; 大文字であるか小文字であるか)を持つ文字である場合、 反対側のケースの対応する文字に置き換わりうる。 その動作についてはcurrent readtableのreadtable caseに依存し、 23.1.2節(Effect of Readtable Case on the Lisp Reader)で概説している。 x はトークンを開始するために使われ、ステップ8に進む。

  4. この時点ではトークンが集約されている途中であり、 複数エスケープ文字には偶数回遭遇している。 もしファイルの終端であればステップ10に進む。 そうでなければ、文字 y がリードされ、 その文法型に従って以下のアクションの1つが実行される。

  • y が終端マクロ文字または非終端マクロ文字の場合:

    • y がケースを持つ文字の場合、反対側のケースの対応する文字に置き換わりうる。 その動作についてはcurrent readtableのreadtable caseに依存し、 23.1.2節(Effect of Readtable Case on the Lisp Reader)で概説している。

    • y はトークンに追加される。

    • ステップ8が繰り返される。

  • y が単一エスケープ文字の場合、その次の文字 z が読み込まれる。 ただしファイルの終わりであれば end-of-file 型のエラーが送出される。 z はその構成特性がalphabetic[2]である場合だけ構成文字として扱う。 z はトークンに追加され、ステップ8が繰り返される。

  • y が複数エスケープ文字である場合、ステップ9に進む。

  • y が不正な文字である場合、型 reader-error のエラーが送出される。

  • y が終端マクロ文字である場合、トークンを終わらせる。 まず、文字 y がアンリード(unread)され(unread-charを参照のこと)、 ステップ10に進む。

  • y が空白文字(whitespace[2] character)の場合、トークンを終わらせる。 まず、 y が空白文字である時に文字 y がアンリードされ(read-preserving-whitespaceを参照のこと)、 ステップ10に進む。

  1. この時点ではトークンは集約されている途中であり、複数エスケープ文字には奇数回遭遇している。 ファイルの終端であれば、型 end-of-file のエラーが送出される。 そうでなければ、文字 y がリードされ、 文字 y の文法型に従って以下のアクションの1つが実行される:
  • y が構成文字、マクロ文字、空白文字(whitespace[2] character)のいずれかである場合、 y は構成特性がalphabetic[2]である場合のみ構成文字として扱われる。 y はトークンに追加され、ステップ9が繰り返される。

  • y が単一マクロ文字の場合、その次の文字 z がリードされる。 ただしファイルの終端の場合は型 end-of-file のエラーが送出される。 z はその構成特性がalphabetic[2]である時に限り構成文字として扱う。 z はトークンに追加され、ステップ9が繰り返される。

  • y が複数エスケープ文字の場合、ステップ8に進む。

  • y が不正な文字であるならば、型 reader-error のエラーが送出される。

  1. この時点ではトークン全体が集約されている。read操作の結果としてトークンを表すオブジェクトが返される。 ただしトークンの文法が不正である場合は型 reader-error のエラーが送出される。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment