# 23.2. `shlex` --- 単純な字句解析

バージョン 1.5.2 で追加.

ソースコード: Lib/shlex.py

`shlex` クラスは Unix シェルを思わせる単純な構文に対する字句解析器を簡単に書けるようにします。このクラスはしばしば、 Python アプリケーションのための実行制御ファイルのような小規模言語を書く上で便利です。

Python 2.7.3 以前はこのモジュールは今のところ Unicode 入力をサポートしていませんでした。

`shlex` モジュールは以下の関数を定義します。

`shlex.``split`(s[, comments[, posix]])

  シェル類似の文法を使って、文字列 s を分割します。 comments が `False` (デフォルト値) の場合、受理した文字列内のコメントを解析しません (`shlex` インスタンスの `commenters` メンバの値を空文字列にします)。この関数はデフォルトでは POSIX モードで動作し、 posix 引数が false の場合は non-POSIX モードで動作します。

  バージョン 2.3 で追加.

  バージョン 2.6 で変更: posix パラメータを追加。

  注釈

  `split()` 関数は `shlex` クラスのインスタンスを利用するので、 s に `None` を渡すと標準入力から分割する文字列を読み込みます。

`shlex` モジュールは以下のクラスを定義します。

class `shlex.``shlex`([instream[, infile[, posix]]])

  `shlex` クラスとサブクラスのインスタンスは、字句解析器オブジェクトです。初期化引数を与えると、どこから文字を読み込むかを指定できます。指定先は `read()` メソッドと `readline()` メソッドを持つファイル/ストリーム類似オブジェクトか、文字列でなくてはいけません（文字列が受理されるようになったのは Python 2.3 以降）。引数が与えられなければ、 `sys.stdin` から入力を受け付けます。第 2 引数は、ファイル名を表す文字列で、 `infile` メンバの値の初期値を決定します。 instream 引数が省略された場合や、この値が `sys.stdin` である場合、第2引数のデフォルト値は "stdin" になります。 posix 引数は Python 2.3 で導入されました。これは動作モードを定義します。 posix が真でない場合（デフォルト）、 `shlex` インスタンスは互換モードで動作します。 POSIX モードで動作中、 `shlex` は、できる限り POSIX シェルの解析規則に似せようとします。

参考

`ConfigParser` モジュール
  Windows `.ini` ファイルに似た設定ファイルのパーザ。

## 23.2.1. shlex オブジェクト

`shlex` インスタンスは以下のメソッドを持っています:

`shlex.``get_token`()

  トークンを一つ返します。トークンが `push_token()` で使ってスタックに積まれていた場合、トークンをスタックからポップします。そうでない場合、トークンを一つ入力ストリームから読み出します。読み出し即時にファイル終了子に遭遇した場合、 `eof` (非 POSIX モードでは空文字列 (`''`)、POSIX モードでは `None`) が返されます。

`shlex.``push_token`(str)

  トークンスタックに引数文字列をスタックします。

`shlex.``read_token`()

  生 (raw) のトークンを読み出します。プッシュバックスタックを無視し、かつソースリクエストを解釈しません (通常これは便利なエントリポイントではありません。完全性のためにここで記述されています)。

`shlex.``sourcehook`(filename)

  `shlex` がソースリクエスト (下の `source` を参照してください) を検出した際、このメソッドはその後に続くトークンを引数として渡され、ファイル名と開かれたファイル類似オブジェクトからなるタプルを返すとされています。

  通常、このメソッドはまず引数から何らかのクオートを剥ぎ取ります。処理後の引数が絶対パス名であった場合か、以前に有効になったソースリクエストが存在しない場合か、以前のソースが (`sys.stdin` のような) ストリームであった場合、この結果はそのままにされます。そうでない場合で、処理後の引数が相対パス名の場合、ソースインクルードスタックにある直前のファイル名からディレクトリ部分が取り出され、相対パスの前の部分に追加されます (この動作は C 言語プリプロセッサにおける `#include "file.h"` の扱いと同様です) 。

  これらの操作の結果はファイル名として扱われ、タプルの最初の要素として返されます。同時にこのファイル名で `open()` を呼び出した結果が二つ目の要素になります (注意: インスタンス初期化のときとは引数の並びが逆になっています！)

  このフックはディレクトリサーチパスや、ファイル拡張子の追加、その他の名前空間に関するハックを実装できるようにするために公開されています。 'close' フックに対応するものはありませんが、shlex インスタンスはソースリクエストされている入力ストリームが EOF を返した時には `close()` を呼び出します。

  ソーススタックをより明示的に操作するには、 `push_source()` および `pop_source()` メソッドを使ってください。

`shlex.``push_source`(stream[, filename])

  入力ソースストリームを入力スタックにプッシュします。ファイル名引数が指定された場合、以後のエラーメッセージ中で利用することができます。 `sourcehook()` メソッドが内部で使用しているのと同じメソッドです。

  バージョン 2.1 で追加.

`shlex.``pop_source`()

  最後にプッシュされた入力ソースを入力スタックからポップします。字句解析器がスタック上の入力ストリームの EOF に到達した際に利用するメソッドと同じです。

  バージョン 2.1 で追加.

`shlex.``error_leader`([file[, line]])

  このメソッドはエラーメッセージの論述部分を Unix C コンパイラエラーラベルの形式で生成します; この書式は `'"%s", line %d: '` で、 `%s` は現在のソースファイル名で置き換えられ、 `%d` は現在の入力行番号で置き換えられます (オプションの引数を使ってこれらを上書きすることもできます)。

  このやり方は、 `shlex` のユーザに対して、Emacs やその他の Unix ツール群が解釈できる一般的な書式でのメッセージを生成することを推奨するために提供されています。

`shlex` サブクラスのインスタンスは、字句解析を制御したり、デバッグに使えるような public なインスタンス変数を持っています:

`shlex.``commenters`

  コメントの開始として認識される文字列です。コメントの開始から行末までのすべてのキャラクタ文字は無視されます。標準では単に `'#'` が入っています。

`shlex.``wordchars`

  複数文字からなるトークンを構成するためにバッファに蓄積していくような文字からなる文字列です。標準では、全ての ASCII 英数字およびアンダースコアが入っています。

`shlex.``whitespace`

  空白と見なされ、読み飛ばされる文字群です。空白はトークンの境界を作ります。標準では、スペース、タブ、改行 (linefeed) および復帰 (carriage-return) が入っています。

`shlex.``escape`

  エスケープ文字と見なされる文字群です。これは POSIX モードでのみ使われ、デフォルトでは `'\'` だけが入っています。

  バージョン 2.3 で追加.

`shlex.``quotes`

  文字列引用符と見なされる文字群です。トークンを構成する際、同じクオートが再び出現するまで文字をバッファに蓄積します (すなわち、異なるクオート形式はシェル中で互いに保護し合う関係にあります)。標準では、ASCII 単引用符および二重引用符が入っています。

`shlex.``escapedquotes`

  `quotes` のうち、 `escape` で定義されたエスケープ文字を解釈する文字群です。これは POSIX モードでのみ使われ、デフォルトでは `'"'` だけが入っています。

  バージョン 2.3 で追加.

`shlex.``whitespace_split`

  この値が `True` であれば、トークンは空白文字でのみで分割されます。たとえば `shlex` がシェル引数と同じ方法で、コマンドラインを解析するのに便利です。

  バージョン 2.3 で追加.

`shlex.``infile`

  現在の入力ファイル名です。クラスのインスタンス化時に初期設定されるか、その後のソースリクエストでスタックされます。エラーメッセージを構成する際にこの値を調べると便利なことがあります。

`shlex.``instream`

  `shlex` インスタンスが文字を読み出している入力ストリームです。

`shlex.``source`

  このメンバ変数は標準で `None` を取ります。この値に文字列を代入すると、その文字列は多くのシェルにおける `source` キーワードに似た、字句解析レベルでのインクルード要求として認識されます。すなわち、その直後に現れるトークンをファイル名として新たなストリームを開き、そのストリームを入力として、EOF に到達するまで読み込まれます。新たなストリームの EOF に到達した時点で `close()` が呼び出され、入力は元の入力ストリームに戻されます。ソースリクエストは任意のレベルの深さまでスタックしてかまいません。

`shlex.``debug`

  このメンバ変数が数値で、かつ `1` またはそれ以上の値の場合、 `shlex` インスタンスは動作に関する冗長な進捗報告を出力します。この出力を使いたいなら、モジュールのソースコードを読めば詳細を学ぶことができます。

`shlex.``lineno`

  ソース行番号 (遭遇した改行の数に 1 を加えたもの) です。

`shlex.``token`

  トークンバッファです。例外を捕捉した際にこの値を調べると便利なことがあります。

`shlex.``eof`

  ファイルの終端を決定するのに使われるトークンです。非 POSIX モードでは空文字列 (`''`) 、POSIX モードでは `None` が入ります。

  バージョン 2.3 で追加.

## 23.2.2. 解析規則

非 POSIX モードで動作中の `shlex` は以下の規則に従おうとします。

- ワード内の引用符を認識しない (`Do"Not"Separate` は単一ワード `Do"Not"Separate` として解析されます)
- エスケープ文字を認識しない
- 引用符で囲まれた文字列は、引用符内の全ての文字リテラルを保持する
- 閉じ引用符でワードを区切る (`"Do"Separate` は、 `"Do"` と `Separate` であると解析されます)
- `whitespace_split` が `False` の場合、wordchar、 whitespace または quote として宣言されていない全ての文字を、単一の文字トークンとして返す。 `True` の場合、 `shlex` は空白文字でのみ単語を区切る。
- 空文字列 (`''`) で EOF を送出する
- 引用符に囲んであっても、空文字列を解析しない

POSIX モードで動作中の `shlex` は以下の解析規則に従おうとします。

- 引用符を取り除き、引用符で単語を分解しない (`"Do"Not"Separate"` は単一ワード `DoNotSeparate` として解析されます)
- 引用符で囲まれないエスケープ文字群 (`'\'` など) は直後に続く文字のリテラル値を保持する
- `escapedquotes` でない引用符文字 (`"'"` など) で囲まれている全ての文字のリテラル値を保持する
- 引用符に囲まれた `escapedquotes` に含まれる文字 (`'"'` など) は、 `escape` に含まれる文字を除き、全ての文字のリテラル値を保持する。エスケープ文字群は使用中の引用符、または、そのエスケープ文字自身が直後にある場合のみ、特殊な機能を保持する。他の場合にはエスケープ文字は普通の文字とみなされる。
- `None` で EOF を送出する
- 引用符に囲まれた空文字列 (`''`) を許す