Non-modern Shell Programing (3)

2.3 トークン認識

シェルはファイルから、対話シェルの場合は端末から、sh -cあるいはsystem()の場合は文字列から、行として入力を読む。入力行は無制限の長さを持ちうる。入力行は2つのメジャーモードを用いて構文解析される。2つのメジャーモードとは、通常のトークン認識とヒアドキュメント処理である。

文法からio_hereトークンが認識されている時、次の改行トークンの直後の1個以上の後続行は、1つ以上のヒアドキュメントの本文を形成し、ヒアドキュメント規則に従って構文解析されるものとする。

io_hereを処理していない時、シェルは入力の次の文字に下記の規則のなかで適用可能な最初の規則を適用することで入力をトークンに分解するものとする。トークンは入力の現在位置から下記の規則の1つによって区切られるまでとする。クォートする文字群も含め、トークンを形成する文字群は正確に入力そのままである。トークンが区切られると指示され、トークンに1つも文字が含まれないなら、実際のトークンが分割されるまで処理は継続するものとする。

  1. 入力終端が認識されたら、現在のトークンが区切られる。現在のトークンが存在しなければ、入力終端インジケータがトークンとして返されるものとする。
  2. 前の文字が演算子の部分として用いられており、現在の文字がクォートされておらず、演算子を形成するために現在の文字群とともに用いることができるならば、(演算子トークンの部分として用いられるものとする。
  3. 前の文字が演算子の部分として用いられており、現在の文字が現在の文字列とともに演算子を形成するために用いることができない場合、前の文字を含む演算子は区切られるものとする。
  4. 現在の文字が<バックスラッシュ>やシングルクォートやダブルクォートで、クォートされていないなら、クォートされたテキストの終端まで後続文字群をクォートする影響を及ぼすものとする。クォートの規則はクォートに述べられている。トークン認識の間、実際は置換は実行されないものとする。そして、結果のトークンは(<改行>の連結を除いて)入力に現れた文字群を正確に含んでおり、埋め込まれたクォートや置換演算子、囲んでいるクォートや置換演算子を含めて、<クォテーションマーク>とクォートされたテキストの終端の間が変更されないものとする。トークンはクォートされたフィールドの終端によって区切られないものとする。
  5. 現在の文字がクォートされていない'$'か'`'ならば、クォートされていない開始文字群から、シェルはパラメータ展開やコマンド置換や算術展開のどの候補の始端かを識別するものとする。開始文字群はそれぞれ、'$' または"${"、"$("または'`'、"$(("である。シェルは(引用されている節に説明されているように)展開される単位の終端を決定するために十分な入力を読むものとする。文字群を処理している間に、展開の実体やクォートが置換内で入れ子になっているのが発見された場合、発見された構文で指示されている方法で、シェルは再帰的に処理するものとする。置換の始端から終端までが発見された文字群は、埋め込まれた構文の認識に必要な全ての再帰を許し、埋め込まれた置換演算子やクォート、囲んでいる置換演算子やクォートを含めて、結果のトークンに変更されずに含まれるものとする。トークンは置換の終端によって区切られないものとする。
  6. 現在の文字がクォートされておらず、新しい演算子の最初の文字として用いることができるならば、現在のトークンは(もしあれば)区切られるものとする。現在の文字は次の(演算子トークンの始端として用いるものとする。
  7. 現在の文字がクォートされていない<改行>ならば、現在のトークンは区切られるものとする。
  8. 現在の文字がクォートされていない<空白>ならば、前の文字を含むトークンが区切られ、現在の文字は捨てられるものとする。
  9. 前の文字が単語の部分だったならば、現在の文字はその単語に追加されるものとする。
  10. 現在の文字が'#'ならば、それとそれに続く次の<改行>までの文字群(ただし<改行>は含まない)はコメントとして捨てられる。行を終端する<改行>はコメントの部分として見なされない。
  11. 現在の文字は新しい単語の始端として用いられる。

トークンが区切られたら、シェル文法の文法によって必要とされるように分類される。

SUSv4 - Shell Command Language - 2.3 Token Recognition