この章では字句スキャン処理の概念を紹介し、 Flexのようなツールの必要性を指摘します。 この章の後半部分でFlexを紹介し、 Flexを使うことのできる状況の実例をいくつか紹介します。
UnixおよびCの世界では、 ファイルは通常個々のバイトが連続したものとして扱われます。 個々のバイトを集めてどのようにグループ化するかという点は、 プログラマが決めることです。 このような抽象化は非常に強力です。 というのは、 どのようなファイルであってもこの抽象化方法によって表現することができるからです。 しかしこの方法には短所もあり、 プログラマはほとんど常に生のファイルに対して構造をあてはめなければなりません。 言葉を変えると、 ファイルをより意味のある部分に分割しなければならないということです。 例えば、 コンパイラのある部分はファイルから連続した文字を受け取り、 構文チェッカが理解することのできる構成要素、 例えば、 数値、キーワード、文字列などにグループ化します。 このようなことを行う理由は、 コンパイラの言語パーサが処理を行うのは、 連続した文字に対してではなく、 その言語のシンボルが連続したものに対してだからです。
データベース・アプリケーションや、 バイナリ・ファイルを扱うアプリケーションは、 扱うデータに対してある固定されたフォーマットというものを持っていることが多く、 そのフォーマットを使って入力データから意味を導き出します。 テキストを入力するプログラムは通常これとは反対で、 入力を単語やシンボルに分割しなければならないことが多いのですが、 通常これらの単語やシンボルがどのように配置されているかを示す決まった構造というものは存在しません。 したがって、 テキスト処理を行うプログラムは、 入力された情報を意味のあるシンボルに分割するために、 字句解析もしくは字句スキャンと呼ばれる処理を行う部分を持っていることが多く、 そこで入力情報の分割が行われます。 このようなことを行う関数群のことを字句アナライザもしくは字句スキャナ、 あるいは短く「スキャナ」と呼びます。
一般的に、 スキャナを作成するのは、 プログラマにとって難しいことでも面白いことでもないのですが、 時間のかかる作業になることはあります。 普及しているプログラミング言語のほとんどは、 スキャナの作成を支援する機能が不十分です。 というのは、 連続した文字を単語、トークン、シンボルに分割する組み込みの機能を持っていないからです。 通常はこのような仕事を行うライブラリ・ルーチンが存在しますが、 柔軟でなかったり、 使いにくいものであったり、 あるいは、 ルーチンとのやりとりにあまりに多くのコードが必要になったりすることが多いために、 実装上の細かな点によって根本的な問題が不明瞭にされてしまいます。
1つの良い例が、 C言語で許されているすべての数値型 (浮動小数、10進整数、16進整数、8進整数) を処理するスキャナをC言語で記述する場合です。 これは非常に難しいということはありませんが、 出来上がったコードは通常美しいとはとても言えないものでしょうし、 その保守や拡張は容易でないことが多いのです。
ほとんどのプログラマが即座に断言するように、 他人の書いたコードを保守するのは通常あまり楽しい作業ではありません。 さらに、 美しくないコードを保守するのは、 楽しいというにはほど遠いものです。 このように、 スキャナを書くことが退屈で、 その保守が難しいとなると、 スキャナの作成をより容易にしてくれる方法を考えようとするに足る理由のあったことが読者にもお分かりいただけるでしょう。
========================================================================
========================================================================