|
次のページ
前のページ
目次へ
3. LexLex プログラムは '字句解析器 (Lexer)' と呼ばれるものを生成します。これ は入力に文字列ストリームをとる関数で、キーにマッチする文字列群を見つけ た時に、ある決まった動作をさせることができます。以下はその簡単な例です。
%{ と %} の組で括られる最初のセクションは、出力プログラムでは直接イン クルードされます。これは、stdio.h で定義されている printf が、後で必要 となるためです。 セクションは '%%' で区切られ、二つ目のセクションの第一行は 'stop' キー で始まることになります。入力で 'stop' キーが発現した時は、残り行 ( printf() 呼び出し) が実行されます。 "stop" に加えて、ここでは "start" というほとんど同じ動作をするものも 定義しました。 上記のコードセクションを '%%' で閉じます。 Example 1 をコンパイルするには以下のようにします。
以上により、'example1' というファイルが生成されたと思います。実行する と、キーボードからの入力待ちになります。定義済みのキー ( 即ち、'stop' や 'start') 以外のものを入力すると、それがそのまま出力されます。'stop' を入力すると、'Stop command received' が出力されます。 EOF (^D) でプログラムを終了させることができます。 main() 関数も定義されていないのに、どうやってプログラムが動いたのか不 思議に思われたかもしれません。これは、-ll コマンドでコンパイル時にリン クした libl (liblex) が、main() 関数の定義を含んでいたからです。 3.1 正規表現でのマッチ上記の例は、それ自身ではあまり使えるものではありませんでした。次の例も それほど利用価値のあるものではないのですが、後々重宝することになる、 Lex での正規表現の使い方を例示しています。 Example 2:
この Lex ファイルでは WORD と NUMBER という、二種類のマッチ(トークン) を記述しています。正規表現と聞くとびくついてしまう人もいるかもしれませ んが、ちょっと勉強すればすぐに理解できるようになるものです。NUMBER に 対するマッチを見てみましょう。 [0123456789]+ これは、0123456789 のどれか一文字を含む文字、または文字列が存在すると いう意味です。以下のような簡略表記もできます。 [0-9]+ WORD マッチはもう少し複雑になります。 [a-zA-Z][a-zA-Z0-9]* 前半部分は、'a' から 'z' または 'A' から 'Z' の間の文字列、つまりアル ファベットのどれかという意味です。アルファベットの後には、アルファベッ トもしくはアラビア数字がゼロ個以上続きます。アスタリスクを使っているの は何故でしょう? '+' というのは一個以上のマッチを表しますが、WORD は、 前半部分で既にマッチした一文字のみという可能性もあります。その場合には、 後半部分でのマッチがゼロになってしまうので、'*' とする必要があるのです。 このようにして、多くのプログラミング言語が要求するような、最初の文字が アルファベットで 始まらなくては *ならず*、その後はアラビア数字を含んで も良いというような、変数名の規則に似せたものを作ることができました。つ まり、'temperature1' は良いですが、'1temperature' はだめということにな ります。 Example 1 でやったように、Example 2 をコンパイルしてみてください。それか ら以下の例のようにテキストを入力してみてください。
出力のホワイトスペースがどこから来たのか、不思議に思われたかもしれませ ん。理由は簡単です。これらは、もともと入力に含まれていたものですが、マッ チしないためそのまま出力となって現れたというだけの話です。 Flex の man ページには、使われている正規表現について詳しく載っています。 また、perl の正規表現の man ページ (perlre) を便利だと感じられる方々も たくさんいます - もっとも Flex の正規表現の実装は、perl ほど完全ではあ りませんが。 "[0-9]*" のように、長さゼロのマッチは行わないように注意してください。 字句解析器が混乱してしまい、空文字列とのマッチを繰り返すようなことにな ります。 3.2 C のようなシンタックスをもつもう少し高度な例以下のような設定ファイルを構文解析したいとします。
このファイル内にはいくつものカテゴリ(トークン)があるのがわかります。
対応する Lex ファイルは Example 3 のようになります。
プログラムに設定ファイルを入力すると、この Lex ファイルから (example3.compile を使って)以下のような出力が得られます。
設定ファイルと見比べると、適切に 'トークン化' されたのがわかります。ファ イルの各々の部分で、正規表現によるマッチがとられ、トークンに変換されて います。 これが、YACC を活用するために必要なことなのです。 3.3 おさらいLex は任意の入力から、それぞれの部分が何であるか決定することができる、 ということがわかりました。これを 'トークン化する' といいます。 次のページ 前のページ 目次へ |
[ |