Provided by: manpages-ja_0.5.0.0.20110915-1_all bug

YACC とのインタフェース
       flex の主な使用方法の一つは、 yacc パーサジェネレータと共に使用すること
       です。 yacc パーサは yylex() と言う名前のルーチンを呼び、次の入力トーク
       ンを見付けるものとしています。 このルーチンは、次のトークンの型を返し、
       関連する値をグローバルの yylval に格納するものとされています。 flexyacc と共に使うには、 yacc-d オプションを指定して、 yacc の入力に現
       れる全ての %tokens の定義を含む y.tab.h  ファイルを生成させます。  この
       ファイルは flex スキャナにインクルードされます。 例えばトークンの一つが
       "TOK_NUMBER" である場合、 スキャナの一部分は次のようになっています:

           %{
           #include "y.tab.h"
           %}

           %%

           [0-9]+        yylval = atoi( yytext ); return TOK_NUMBER;

オプション
       flex には以下のようなオプションがあります:

       -b     バックアップ情報を  lex.backup   に出力します。   このファイルに
              は、スキャナのバックアップ(backing-up)を必要とする状態と  それに
              対応する入力文字の一覧がリストされます。  ルールを追加することで
              バックアップ状態を取り除くこと ができます。バックアップ状態が 
               取り除かれ、 -Cf または -CF  を指定すると、生成されたスキャナ
              の実行速度が向上します(  -p フラグを見て下さい)。 スキャナをぎり
              ぎりまで最適化しようとしてるユーザのみが  このオプションに関係あ
              ります。 (後述の性能関連の節を見て下さい。)

       -c     何もしません。POSIX 互換のために用意されています。

       -d     生成されたスキャナが              モードで実行されます。
              yy_flex_debug が非ゼロの場合(デフォルト)、  パターンが認識される
              たびに、スキャナは次のようなメッセージを  へ出力し
              ます。

                  --accepting rule at line 53 ("the matched text")

              行番号はスキャナを定義しているファイル   (flexに与えられたファイ
              ル)   でのルールの位置です。  スキャナがバックアップしたとき、デ
              フォルトルールを受け入れたとき、  入力バッファの最後に到達したと
              き  (あるいは、NULに到達したとき; スキャナには、この二つの区別は
              つきません) 、ファイルの最後に到達した  ときにもメッセージが出力
              されます。

       -f      を指定します。 テーブル圧縮は行われず、標準入出力
              をバイパスします。    その結果生成されるスキャナは大きくなります
              が、高速なものになります。  このオプションは -Cfr と同等です (以
              下を参照)。

       -h     flex のオプションの要約からなる "ヘルプ" を   に書き出し
              終了します。 -?--help とは -h と同じです。

       -i       スキャナを生成します。  flex  の入力パ
              ターンに与えられる文字が大文字であるか小文字であるかは区別され
              ず、  スキャナに入力される文字列は大文字小文字に関係なくマッチし
              ます。 マッチしたテキスト yytext  では入力時の大文字小文字が保存
              されます (大文字を小文字に変換したりしません)。

       -l     AT&T  の lex の実装に対して最大限の互換性を持たせます。これは 
               互換性を意味しません。 このオプションを使用すると性能に大き
              な影響があります。  このオプションは、 -+, -f, -F, -Cf, -CF と同
              時に使用できません。詳しくは、 後述の "Lex および POSIX との非互
              換性"     の節を御覧下さい。    またこのオプションを使用すると、
              YY_FLEX_LEX_COMPAT が生成されたスキャナの名前に  #define  されま
              す。

       -n     何もしません。POSIX 互換のためにだけ用意されたオプションです。

       -p     性能情報を標準エラー出力に出力します。 flex 入力ファイルの記述の
              うち、  生成されるスキャナの性能低下の深刻な原因となる部分につい
              て、  コメントされます。 オプションを2回指定すると、より細かな性
              能低下についても コメントが出力されます。

              REJECT%option yylineno ・可変長右文脈(欠陥/バグの節で後述)は
              多大なる性能への悪影響があります;  yymore()  の使用・ ^ オペレー
              タ・ -I フラグは小さな性能の悪影響があります。

       -s      (マッチしないスキャナの入力を  に出力す
              る) が抑制されます。ルールにマッチしない入力が表れたとき、スキャ
              ナは エラーで異常終了します。 スキャナのルールの組に抜けが無いか
              を確認する場合に有効です。

       -t     lex.yy.c ではなく、標準出力にスキャナを書き出します。

       -v     生成するスキャナの特徴の要約を    に出力するように
              flex に指示します。 ほとんどの特徴は通常の flex ユーザには意味が
              ありませんが、最初の行は  flex のバージョンを表示し( -V で表示さ
              れるもと同じです)、次の行はデフォルトを含むスキャナ生成時のフラ
              グです。

       -w     警告メッセージを抑制します。

       -B       なスキャナ (以下の -I の項を参照) ではなく  なス
              キャナを生成するよう flex に指示します。  通常  -B  を使用するの
              は、スキャナを対話的に使用しないことが    時であり、
               性能を追求したい時です。 より大きい性能を追求する場合に
              は、 -Cf もしくは -CF オプションを使用すべきです(後述)。 -B を自
              動的に設定します。

       -F       スキャナテーブルの表現を使う(標準入出力はバイパスする)こ
              とを指定します。  この表現は、完全テーブル表現 (-f) とほぼ同じぐ
              らい高速で、 ある種のパターンに対してはかなり小さく  (ある種に対
              しては大きく)     なります。    通常、次のように、パターンの組が
              "keywords" とその対応 および "identifier" ルールからなる場合:

                  "case"    return TOK_CASE;
                  "switch"  return TOK_SWITCH;
                  ...
                  "default" return TOK_DEFAULT;
                  [a-z]+    return TOK_ID;

              この場合、完全テーブル表現を使用する方が良いです。          もし
              "identifier" ルールからのみ表現され、 キーワードを検知するために
              ハッシュ表等を使用する場合は、 -F を使用する方が良いです。

              このオプションは -CFr と等価です (以下を参照)。 これは  -+  オプ
              ションとは同時に指定できません。

       -I     flex なスキャナを生成するように指示します。 対話的なス
              キャナは、  先読みすることによりマッチするトークンが完全に決まる
              場合のみ先読みします。  現在のトークンが既に明らかな場合でも常に
              先読みする方法は、 必要時のみ先読みする方法より少し速いです。 し
              かし、常に先読みする方法では対話性能に著しく悪影響があります; 例
              えばユーザが改行を入力した場合、  トークンを入力するまでそれ
              は改行として認識されません。  大概の場合、次の行全体を入力するこ
              とになります。

              flex のスキャナのデフォルトは  であり、例外は -Cf-CF
              といったテーブル圧縮オプション(後述)使用時です。  高性能追求時に
              はこれらのオプションを使用しているべきですので、    これらのオプ
              ションを使用していない場合には、 flex は実行時性能を少し犠牲にし
              て直観的な対話的な振舞いを取っているものとします。 -I オプション
              を  -Cf-CF と共に  ことにも注意して下さい。 実際
              はこのオプションは不要です; 許される場合、デフォルトで有効になっ
              ています。

              isatty()  がスキャナの入力に対して偽を返す場合、 -I が指定されて
              いた場合でも、flex はバッチモードへ戻ります。 なにがあっても対話
              モードを強制するには、  %option  always-interactive  (後述のオプ
              ションを参照) を使用します。

              スキャナを対話的で  ように強制するには  -B  (先述)を使用しま
              す。

       -L     flex#line ディレクティブを lex.yy.c 中に生成しないように指示
              します。 デフォルトではこの #line ディレクティブを生成するので、
              アクションにおけるエラーメッセージは、オリジナルの flex 入力ファ
              イル( エラーが入力ファイルのコードに起因する場合)もしくは ファイ
              ル  lex.yy.c ( flex の誤り -- 以下の電子メールアドレスに報告して
              下さい) における正しい位置を与えます。

       -T     flex モードで実行します。 入力の形式とその結果として
              出力される非決定性/決定性有限  オートマトンに関して 
               に多量のメッセージを出力します。 このオプションは主に flex を
              メンテナンスするために使われます。

       -V     バージョン番号を  に出力して終了します。 --version-V
              と同じです。

       -7     7 ビットのスキャナを生成します。 すなわち、入力に 7 ビットの文字
              のみを使用することを意味します。  -7  を指定する利点は、 -8 オプ
              ション(後述)を指定して生成するテーブルの半分まで小さくなりうるこ
              とです。  欠点は、入力に 8 ビット文字が含まれている時に、 スキャ
              ナがハングもしくはクラッシュすることです。

              しかしながら、 -Cf-CF といったテーブル圧縮オプション使用時に
              はテーブル圧縮の効果は少なく、  移植性が著しく低下することに注意
              して下さい。 flex のデフォルトの動作では、 -Cf-CF,  を指定し
              ない限り  8 ビットスキャナを生成します。 指定時には、 あなたのサ
              イトが常に 8 ビットスキャナを生成するように (USA  以外のサイトで
              は良くあります)していない場合には、  7  ビットスキャナを生成しま
              す。 flex が 7 ビットもしくは 8 ビットのいずれのスキャナを生成す
              るのかを  知りたい場合には、上述の -v の出力のフラグの要約を調べ
              て下さい。

              -Cfe もしくは -CFe (これらのテーブル圧縮オプションおよび等価クラ
              スは後述) を使用しても、flex はデフォルトで 8 ビットスキャナを生
              成することに 注意して下さい。 なぜなら、完全な 8  ビットテーブル
              は 7 ビットテーブルと比べても たいして高価にはならないからです。

       -8     8 ビットのスキャナを生成するように flex に指示します。すなわち 8
              ビット文字を解釈します。 圧縮オプション -Cf-CF  使用時にのみ
              必要です。 なぜなら flex はデフォルトでは 8 ビットスキャナを生成
              するからです。

              flex のデフォルト動作と 7 ビットおよび 8 ビットスキャナの トレー
              ドオフに関しては、上記 -7 の議論を見て下さい。

       -+     C++ のスキャナクラスを生成します。 詳しくは C++ スキャナの生成で
              後述します。

       -C[aefFmr]
              テーブル圧縮の程度と、    より一般的には小さいスキャナと高速なス
              キャナとのトレードオフを指定します。

              -Ca ("アライン") 生成されるスキャナのテーブルは、 メモリアクセス
              および計算のためにアラインされるため、より大きなものになります。
              RISC アーキテクチャではロングワードのフェッチおよび操作は ショー
              トワードといったより小さな大きさのものに対するものより効率的で
              す。  場合によってはスキャナのテーブルサイズが通常の 2倍になるこ
              ともあります。

              -Ce  (同一の字句属性を持つ文字セット)を構築します  (例
              えば、  flex 入力中に数字が現れるのが文字クラス "[0-9]" のみの場
              合、 数字 '0', '1', ...,  '9'  は全て同じ等価クラスになります)。
              多くの場合、等価クラスを用いることで最終的なテーブル/ オブジェク
              トファイルのサイズを劇的(平均して   1/2-1/5)に減らすことが出来ま
              す。  また、その際の性能コストは非常に低く抑えられます ( 1文字ス
              キャンするごとに 1回の配列検索を行うだけです)。

              -Cf (full) スキャナテーブルを生成することを指示します - flex
              は、別の状態に関する類似した遷移関数をうまく利用するという、
              テーブル圧縮手法を用いません。

              -CF 別の高速スキャナ表現( -F フラグにて記述)を用いることを指定し
              ます。 このオプションは -+ と同時に使用できません。

              -Cm flex を構築するよう指示します。 メタ等価ク
              ラスは一緒に使われることの多い等価クラス (等価クラスが使われてい
              ないときには文字群)  の集合です。 圧縮テーブルを使っているとき、
              メタ等価クラスは多くの場合にかなりの効果的をもたらしますが、  や
              や性能に影響します  (1-2 回の条件テストと 1 回の配列検索がスキャ
              ンした文字ごとに行われます)。

              -Cr  生成されたスキャナは入力に対しては標準入出力ライブラリ(標準
              入出力)を   します。 スキャナは、 fread()getc() では
              なく、 read() システムコールを使用します。  性能改善結果はシステ
              ムに依存します。  オプション -Cf もしくは -CF を使用していない場
              合には、 一般にこのオプションは性能をあまり改善しません。 -Cr を
              指定すると、例えばスキャナを設定する前に標準入出力を使用して
              yyin を読み取る等した場合奇妙な動作となり得ます  (標準入出力の入
              力バッファに以前読み込んだものを、スキャナは読めません)。

              -CrYY_INPUT を定義した場合意味がありません (前述の生成された
              スキャナを参照)。 スキャナの呼出に先だって標準入力を使って  yyin
              から読みだしているときには、予想外の振る舞いをすることがありま
              す。

              -C  のみを指定したときには、スキャナはテーブル圧縮は行いますが、
              等価クラスもメタ等価クラスも使いません。

              オプション  -Cf-CF はオプション -Cm を同時に指定しても意味を
              なしません -  なぜなら、テーブル圧縮が行われないときメタ等価クラ
              ス は現れないからです。 それ以外のオプションは自由に組み合わせる
              ことが出来ます。

              デフォルトの設定は -Cem です。このとき flex は等価クラスとメタ等
              価クラスを生成します。    この設定は最も高いテーブル圧縮を行いま
              す。  テーブルサイズの大きさと実行の高速性はトレードオフの関係に
              あり、 一般に

                  遅いが 小さい
                        -Cem
                        -Cm
                        -Ce
                        -C
                        -C{f,F}e
                        -C{f,F}
                        -C{f,F}a
                  速いが 大きい

              となります。  小さいテーブルのスキャナは通常生成もコンパイルも高
              速であるため、 通常の開発時は最大の圧縮を行うでしょう。

              製品のスキャナでは、 -Cfe が速度と大きさの良いバランスです。

       -ooutput
              lex.yy.c ではなくファイル output にスキャナを書くように flex  に
              指示します。 -o-t オプションを組み合わせると、 スキャナは 
               に書かれますが、 #line ディレクティブ( -L にて上述)はファ
              イル output を参照します。

       -Pprefix
              flex  の使うデフォルトのプレフィックス yy の代わりに prefix を使
              います。これはグローバル変数とファイル名に影響します。    例えば
              -Pfoo とすると、 yytext の名前は footext となります。 またデフォ
              ルトの出力ファイル名を lex.yy.c から lex.foo.c に変えます。 影響
              を受ける名前の一覧です:

                  yy_create_buffer
                  yy_delete_buffer
                  yy_flex_debug
                  yy_init_buffer
                  yy_flush_buffer
                  yy_load_buffer_state
                  yy_switch_to_buffer
                  yyin
                  yyleng
                  yylex
                  yylineno
                  yyout
                  yyrestart
                  yytext
                  yywrap

              (C++ スキャナ使用時には yywrapyyFlexLexer だけが影響を受けま
              す。) スキャナの中では、グローバル変数および関数を  どちらの名前
              ででも参照できます; 外部的には修正した名前のみ持ちます。

              このオプションを使用することにより、複数の flex プログラムを同一
              の実行形式に容易にリンクすることが出来ます。    しかし、このオプ
              ションは yywrap() の名前をも変えますので、 独自の(適切に名前を付
              けた)ルーチンをスキャナのために用意するか、 %option noyywrap  を
              使用して  -ll とリンクする  どれもデフォルトでは
              提供されません。

       -Sskeleton_file
              flex がスキャナを構築するのに使うデフォルトの スケルトンファイル
              に優先します。 flex のメンテナンスや開発をする場合以外、このオプ
              ションは必要ありません。

       flex は、flex のコマンドラインではなく、 スキャナ仕様記述中からオプショ
       ンを制御する機構を提供します。   これはスキャナの最初の部分に   %option
       ディレクティブを含めることで実現できます。 単一の %option  ディレクティ
       ブにおいて複数のオプションを指定でき、  また複数のディレクティブを flex
       入力ファイルの最初の部分に置くことが出来ます。

       ほとんどのオプションが単純な名前であり、 オプションとして前に "no" とい
       う語(空白をはさみません)を付けて  意味を反転できます。 数値は flex のフ
       ラグやその反転と等価です。

           7bit            -7 オプション
           8bit            -8 オプション
           align           -Ca オプション
           backup          -b オプション
           batch           -B オプション
           c++             -+ オプション

           caseful または
           case-sensitive  -i オプションの逆(デフォルト)

           case-insensitive または
           caseless        -i オプション

           debug           -d オプション
           default         -s オプションの逆
           ecs             -Ce オプション
           fast            -F オプション
           full            -f オプション
           interactive     -I オプション
           lex-compat      -l オプション
           meta-ecs        -Cm オプション
           perf-report     -p オプション
           read            -Cr オプション
           stdout          -t オプション
           verbose         -v オプション
           warn            -w オプションの逆
                           (-w オプションには "%option nowarn" を使用して下さい)

           array           "%array" と等価
           pointer         "%pointer" と等価(デフォルト)

       %option には、他では利用できない機能を提供するものもあります:

       always-interactive
              入力を常に "対話的" に扱うスキャナを生成するように flex に指示し
              ます。  通常、新たな入力ファイル毎にスキャナは isatty() を呼び出
              し、スキャナの入力元が対話的であり 1 度に  1  文字ずつ読むべきか
              どうか判定しようとします。  一方このオプションを使用するとこの様
              な呼び出しは行いません。

       main   スキャナに対し、 yylex() を呼び出すだけのデフォルトの main()  プ
              ログラムを提供するように指示します。  このオプションは  noyywrap
              (後述)も暗黙的に指示します。

       never-interactive
              入力を "対話的" とはしないスキャナを生成するように flex に指示し
              ます  (これもまた  isatty()  を呼び出しません)。  これは always-
              interactive の逆です。

       stack  開始条件スタックの使用を有効にします(前述の開始条件を参照)。

       stdinit
              設定されている場合 (すなわち %option stdinit) yyin および  yyout
              を、 デフォルトの nil ではなく、  に設定しま
              す。 既存の lex プログラムには、 ANSI C 互換ではないものの、この
              動作に依存しているものがあります。  ANSI C では 
               がコンパイル時の定数である必要はありません。

       yylineno
              入力から読み取った現在の行番号をグローバル変数 yylineno に保持す
              るスキャナを生成するように、  flex に指示します。 このオプション
              は %option lex-compat から暗黙的に指定されます。

       yywrap セットされていない場合 (すなわち %option noyywrap)  、スキャナは
              ファイルの終りに際し yywrap() を呼ばず単にスキャンすべきファイル
              がもう無いものとするようになります( ユーザが yyin を新しいファイ
              ルを指すようにし、再度 yylex() を呼び出すまでです)。

       flex はルールアクションをスキャンし、 REJECTyymore() の機能が使われ
       ているかどうかを調べます。 rejectyymore  のオプションを使用すると、
       オプションで指定した通りにこの判定に優先します。       オプションの指定
       は、セットして機能を使用していることを示す(例えば %option reject)  、も
       しくはアンセットして機能を使用していないことを示す(例えば       %option
       noyymore) ものとします。

       次のオプションは文字列の値を取り、'=' で区切ります:

           %option outfile="ABC"

       これは -oABC と同じであり、

           %option prefix="XYZ"

       は -PXYZ と同じです。 最後に、

           %option yyclass="foo"

       は C++ スキャナ生成時のみ有効( -+ オプション)です。これは  flex  に対し
       て、  fooyyFlexLexer のサブクラスであることを知らせますので、 flex
       はアクションを yyFlexLexer::yylex() ではなく foo::yylex()  のメンバ関数
       とします。  また、( yyFlexLexer::LexerError() を起動することにより)呼び
       出すと実行時エラーを除去する yyFlexLexer::yylex()  メンバ関数を生成しま
       す。 詳細は後述の C++ スキャナの生成を見て下さい。

       生成されたスキャナから不要なルーチンを除きたい  lint 純正主義者のために
       多くのオプションが用意されています。      以下をアンセットすると(例えば
       %option nounput )、対応するルーチンは生成されるスキャナから除かれます:

           input, unput
           yy_push_state, yy_pop_state, yy_top_state
           yy_scan_buffer, yy_scan_bytes, yy_scan_string

       ( yy_push_state() 等は %option stack を使用しない場合には現れません)。

性能関連
       flex  の主なデザインゴールは高性能なスキャナを生成することです。 多くの
       ルールセットを良く扱うことで最適化されます。 既に概説した -C オプション
       使用によるテーブル圧縮に起因する速度への影響の他に、 性能を悪化させる多
       くのオプション/アクションがあります。  それらを高価なものから安価なもの
       へと並べます:

           REJECT
           %option yylineno
           自由長の右文脈(trailing context)

           バックアップが必要なパターンの組
           %array
           %option interactive
           %option always-interactive

           '^' 行頭オペレータ
           yymore()

       最初の 3 つは非常に高価であり、最後の 2 つは非常に安価です。 unput() は
       潜在的に非常に大きな仕事をするルーチン呼び出しとして実装されているのに
       対し、  yyless() は非常に安価なマクロです; ですからスキャンした余分なテ
       キストを戻すだけの場合には yyless() を使って下さい。

       性能が重要な場合には、出来うる限りの努力でもって  REJECT   を避けて下さ
       い。 これは特に高価なオプションです。

       バックアップを取り除くと、乱雑になり、 ひどく苦労して複雑なスキャナを作
       ることになります。 実際的には -b フラグを指定して lex.backup ファイルを
       生成することから始めます。例えば、入力

           %%
           foo        return TOK_KEYWORD;
           foobar     return TOK_KEYWORD;

       に対しては、ファイルは次のようになります:

           State #6 is non-accepting -
            associated rule line numbers:
                  2       3
            out-transitions: [ o ]
            jam-transitions: EOF [ \001-n  p-\177 ]

           State #8 is non-accepting -
            associated rule line numbers:
                  3
            out-transitions: [ a ]
            jam-transitions: EOF [ \001-`  b-\177 ]

           State #9 is non-accepting -
            associated rule line numbers:
                  3
            out-transitions: [ r ]
            jam-transitions: EOF [ \001-q  s-\177 ]

           Compressed tables always back up.

       最初の数行は、  'o'  に遷移できるが他の文字には遷移できない状態があり、
       その状態では現在スキャンされたテキストは他のルールにはマッチしないこと
       を 表します。 この状態が発生したのは、 入力ファイルの行 2, 3 のルールに
       マッチしようとした時です。 スキャナがこの様な状態にあり 'o'  以外の文字
       を読んだ場合には、 マッチするルールを探すためのバックアップが必要となり
       ます。 少し考えれば、これは "fo" を見た時にある状態に違いないことが分か
       るでしょう。  この様な時、'o'  以外のものが現れると、  スキャナは、単に
       'f' にマッチする(デフォルトルール)ところまで 戻り(バックアップし)ます。

       状態 #8 に関係するコメントは、 "foob"  がスキャンされた時に問題があるこ
       とを表しています。  実際、'a' 以外の文字に出会うと、スキャナは "foo" を
       受理するところまで戻ります。   同様に状態   #9   に関係するコメントは、
       "fooba" がスキャンされ 'r' が続かない場合に関係します。

       最後のコメントが通知するのは、 -Cf-CF を使っているのでなければ バッ
       クアップを取り除こうと努力することは無意味であることです。 なぜなら、圧
       縮されたスキャナに対してそのようなことをしても、 性能上の利益は無いから
       です。

       バックアップを取り除くためには "エラー" ルールを追加します:

           %%
           foo         return TOK_KEYWORD;
           foobar      return TOK_KEYWORD;

           fooba       |
           foob        |
           fo          {
                       /* false alarm, not really a keyword */
                       return TOK_ID;
                       }

       キーワードのリストからバックアップを取り除くには、"全てを捕まえる" ルー
       ルを使用することが出来ます:

           %%
           foo         return TOK_KEYWORD;
           foobar      return TOK_KEYWORD;

           [a-z]+      return TOK_ID;

       通常、適切な時にはこれは一番良い解決策です。

       バックアップメッセージはカスケードすることが多いです。 複雑なルールの組
       では、数百ものメッセージを得るのは普通のことです。 しかし、これを解析す
       れば、バックアップを除去するためには 大抵の場合数ダースのルールにだけ関
       係あることが分かるでしょう  (しかし、間違えることが多く、誤ったルールが
       偶然有効なトークンにマッチし得ます。  将来の flex の機能では、 自動的に
       バックアップを除去するルールを追加するようになるかも知れません)。

       バックアップを除去することにより利益があるのは、   バックアップを
       除去した時だけということを覚えておくことは重要です。 たった一つを残して
       も何も得ることが出来ません。

        右文脈 (左部分と右部分のいずれかもしくは両方が可変長)は REJECT
       とほぼ同じだけの(すなわち相当の)性能劣化となります。 そのため次のような
       ルール:

           %%
           mouse|rat/(cat|dog)   run();

       は次のように書くか:

           %%
           mouse/cat|dog         run();
           rat/cat|dog           run();

       次のように書いた方が良いです:

           %%
           mouse|rat/cat         run();
           mouse|rat/dog         run();

       特別な '|' アクションは助けにはなり  し、かえって状況を悪くします
       (後述の欠陥/バグを参照)。

       スキャナの性能を向上させるための余地(実現は最も容易)は、 マッチするトー
       クンが長ければスキャナが高速になることにあります。 長いトークンではほと
       んどの入力処理は(短い)内部ループで処理され、 アクションのためにスキャナ
       環境を設定する追加の仕事(例えば yytext) をほとんどしないからです。 C コ
       メントのスキャナを思い出しましょう:

           %x comment
           %%
                   int line_num = 1;

           "/*"         BEGIN(comment);

           <comment>[^*\n]*
           <comment>"*"+[^*/\n]*
           <comment>\n             ++line_num;
           <comment>"*"+"/"        BEGIN(INITIAL);

       次のように書くと高速になります:

           %x comment
           %%
                   int line_num = 1;

           "/*"         BEGIN(comment);

           <comment>[^*\n]*
           <comment>[^*\n]*\n      ++line_num;
           <comment>"*"+[^*/\n]*
           <comment>"*"+[^*/\n]*\n ++line_num;
           <comment>"*"+"/"        BEGIN(INITIAL);

       今度は、改行毎に別のアクションの処理を行うのではなく、 改行認識はルール
       間で "分散"  され、  可能な限り長いテキストにマッチするようになっていま
       す。 ルールの  はスキャナを遅く !  スキャナの速度は、ルール
       数とも、 オペレータ '*' や '|' といったものに基づくルールの複雑さ (この
       節の始めで扱いました)とも独立です。

       最後の高速化の例です:  1  行に 1 つずつであり別の文字は付かないような、
       識別子とキーワードを全てファイルからスキャンすることを考えます。 最初は
       次のようになるでしょう:

           %%
           asm      |
           auto     |
           break    |
           ... etc ...
           volatile |
           while    /* it's a keyword */

           .|\n     /* it's not a keyword */

       後戻りを避けるために全てを捕まえるルールを導入します:

           %%
           asm      |
           auto     |
           break    |
           ... etc ...
           volatile |
           while    /* it's a keyword */

           [a-z]+   |
           .|\n     /* it's not a keyword */

       1  行に正確に  1  語だけあることが保証されている場合、 改行の認識を別の
       トークンと併せることで、 マッチの総数を半分に減らすことが出来ます:

           %%
           asm\n    |
           auto\n   |
           break\n  |
           ... etc ...
           volatile\n |
           while\n  /* it's a keyword */

           [a-z]+\n |
           .|\n     /* it's not a keyword */

       ここで、再度バックアップをスキャナに組み込んだことに 気を付けなければな
       りません。 実際  入力ストリームはレターと改行だけであることを知っ
       ていますが、 flex はこれが分からないため、 トークン "auto" などをスキャ
       ンした次の文字が改行でもレターでもない場合には バックアップが必要である
       と考えます。  以前は  "auto"  ルールに適合しそれで終りでしたが、   今は
       "auto" ルールは無く、"auto\n" ルールだけがあります。 バックアップの可能
       性を除去するためには、 最後の改行以外のルールを二重化するか、  そのよう
       な入力に出くわさないので分類は不要と分かっているため、 改行を導入しない
       もう一つの全てを捕まえるルールを導入することが出来ます:

           %%
           asm\n    |
           auto\n   |
           break\n  |
           ... etc ...
           volatile\n |
           while\n  /* it's a keyword */

           [a-z]+\n |
           [a-z]+   |
           .|\n     /* it's not a keyword */

       -Cf を付けてコンパイルすると、実際問題上 flex  で得られるほぼ最速になり
       ます。

       最後の注意事項:  flex  は  NUL にマッチする時には遅く、トークンが複数の
       NUL を含む時には特に遅いです。 テキストがしばしば NUL  を含むものと予想
       される場合には、テキストの   部分とマッチするようにルールを書くべき
       です。

       もう一つの性能に関する最終注意事項:  入力のマッチ方法の節で既に示したよ
       うに、 大きなトークンを納めるために yytext のサイズを動的に変更すると処
       理が遅くなります。 なぜなら、(巨大な)トークンを再度先頭からスキャンしな
       おさねばならないからです。  性能が重要な場合、 テキストの "大きな" 部分
       にマッチさせるべきですが "巨大な"  部分にマッチさせる  べきではありませ
       ん。 両者の堺目は 8K 文字/トークンです。

C++ スキャナの生成
       flex  は  2 通りの C++ スキャナ生成方法を提供します。 最初の方法は flex
       が生成したスキャナを単に C コンパイラではなく C++ コンパイラで コンパイ
       ルするというものです。   この場合コンパイルエラーには出会わないはずです
       (見付けた場合には作者の節で後述する電子メールアドレスに報告して下さ
       い)。  この場合ルールにおいて C コードではなく C++ コードを書くことが出
       来ます。 スキャナのデフォルトの入力元は yyin のままであり、  デフォルト
       のエコー先は  yyout  のままであることに注意して下さい。 どちらも FILE *
       変数のままであり、C++ streams ではないです。

       flex に C++ スキャナクラスを生成させることも出来ます。 -+  オプションを
       指定する(もしくは等価的に   %option  c++  を使う)とこのように実行され、
       flex の実行形式名が '+' で終っている場合には自動的に指定されます。 この
       オプションを指定すると   flex  が生成するスキャナのデフォルトはファイル
       lex.yy.cc となり lex.yy.c ではありません。 生成されたスキャナは 2  つの
       C++ クラスとのインタフェースを定義するヘッダファイル FlexLexer.h をイン
       クルードします。

       最初のクラス FlexLexer は一般的なスキャナクラスを定義する抽象基盤クラス
       を提供します。 以下のメンバ関数を提供します:

       const char* YYText()
              最後にマッチしたテキストを返します。 yytext と等価です。

       int YYLeng()
              最後にマッチしたトークンの長さを返します。 yyleng と等価です。

       int lineno() const
              現在の入力の行番号(   %option   yylineno  参照)もしくは  %option
              yylineno を使用していない場合には 1 を返します。

       void set_debug( int flag )
              スキャナのデバッグフラグをセットします。 yy_flex_debug  に代入す
              るのと同じです(オプションの節で前述)。  スキャナ構築時に %option
              debug を使用してデバッグ情報を組み込む必要があることに注意して下
              さい。

       int debug() const
              現在のデバッグフラグの設定を返します。

       また次のものと等価なメンバ関数も提供されます     yy_switch_to_buffer(),
       yy_create_buffer()  (最初の引数は  istream*  オブジェクトポインタであり
       FILE*     ではありません),    yy_flush_buffer(),    yy_delete_buffer(),
       yyrestart()  (これもまた最初の引数は  istream*   オブジェクトポインタで
       す)。

       2   番目のクラスは   FlexLexer.h   で定義される   yyFlexLexer  であり、
       FlexLexer から導出したものです。 以下の追加のメンバ関数を定義します:

       yyFlexLexer( istream* arg_yyin = 0, ostream* arg_yyout = 0 )
              与えられた入出力ストリームを使う yyFlexLexer  オブジェクトを構築
              します。 指定しない場合にはそれぞれストリームのデフォルト cincout になります。

       virtual int yylex()
              これは yylex() が通常の flex  スキャナに対して行ったのと同様の役
              割を担います:  ルールのアクションが値を返すまで、 入力ストリーム
              をスキャンし、トークンを消費します。 yyFlexLexer  からサブクラス
              S を導出し yylex() から S のメンバ関数および変数をアクセスしたい
              場合、 %option yyclass="S" を指定して yyFlexLexer ではなくサブク
              ラスを使用することを  flex  に知らせる必要があります。  この場合
              yyFlexLexer::yylex() を生成するのではなく、 flexS::yylex()
              (および呼び出されたなら  yyFlexLexer::LexerError()  を呼び出すダ
              ミーの yyFlexLexer::yylex() も)を生成します。

       virtual void switch_streams(istream* new_in = 0,
              ostream* new_out = 0) yyinnew_in (非ニルの場合) に再割当し、
              yyoutnew_out (同様)に再割当します。 yyin が再割当された場合
              には以前の入力バッファは消去されます。

       int yylex( istream* new_in, ostream* new_out = 0 )
              まず入力ストリームを switch_streams( new_in, new_out )  を使用し
              て切り替え、 yylex() の値を返します。

       さらに、  yyFlexLexer  は次のプロテクトされた仮想関数を定義します。  ス
       キャナにあわせてこれらを導出クラスにおいて再定義出来ます:

       virtual int LexerInput( char* buf, int max_size )
              最大 max_size 文字を buf に読み込み、読めた文字数を返します。 入
              力の終りを示すには 0 文字を返します。"対話的" スキャナ( -B-I
              フラグを参照)はマクロ YY_INTERACTIVE  を定義することに注意して下
              さい。  LexerInput() を再定義し、 対話的な入力元をスキャンする可
              能性があるかどうかに依存して  異なるアクションが必要となる場合、
              この名前が存在するかどうかのテストは #ifdef にて可能です。

       virtual void LexerOutput( const char* buf, int size )
              size  文字をバッファ  buf  から書き出します。 スキャナのルールが
              NUL  を含むテキストにマッチ可能な場合、  NUL  終端されているこの
              バッファは "内部に" NUL を含んでいても構いません。

       virtual void LexerError( const char* msg )
              致命的なエラーメッセージを報告します。    デフォルトのこの関数は
              メッセージをストリーム cerr に書き、終了します。

       yyFlexLexer オブジェクトは   スキャン時の状態を含むことに注意して
       下さい。 それゆえこの様なオブジェクトをリエントラントなスキャナとして使
       用できます。 同一の yyFlexLexer  クラスの複数のインスタンスを具体化可能
       であり、  複数の C++ スキャナクラスを組み合わせ上記 -P オプションを使用
       することで同一のプログラムで使用可能です。

       最後に %array 機能は C++ スキャナクラスでは使用できないことに注意して下
       さい; %pointer を使用しなければなりません(デフォルト)。

       単純な C++ スキャナの例を以下に示します:

               // An example of using the flex C++ scanner class.

           %{
           int mylineno = 0;
           %}

           string  \"[^\n"]+\"

           ws      [ \t]+

           alpha   [A-Za-z]
           dig     [0-9]
           name    ({alpha}|{dig}|\$)({alpha}|{dig}|[_.\-/$])*
           num1    [-+]?{dig}+\.?([eE][-+]?{dig}+)?
           num2    [-+]?{dig}*\.{dig}+([eE][-+]?{dig}+)?
           number  {num1}|{num2}

           %%

           {ws}    /* skip blanks and tabs */

           "/*"    {
                   int c;

                   while((c = yyinput()) != 0)
                       {
                       if(c == '\n')
                           ++mylineno;

                       else if(c == '*')
                           {
                           if((c = yyinput()) == '/')
                               break;
                           else
                               unput(c);
                           }
                       }
                   }

           {number}  cout << "number " << YYText() << '\n';

           \n        mylineno++;

           {name}    cout << "name " << YYText() << '\n';

           {string}  cout << "string " << YYText() << '\n';

           %%

           int main( int /* argc */, char** /* argv */ )
               {
               FlexLexer* lexer = new yyFlexLexer;
               while(lexer->yylex() != 0)
                   ;
               return 0;
               }
       複数の(異なった)字句解析クラスを生成したい場合、  -P  フラグ  (もしくは
       prefix= オプション) を使用して各 yyFlexLexerxxFlexLexer  等の別の名
       前にします。  次に字句解析クラスのソースごとに  <FlexLexer.h>  をインク
       ルードします。 以下のように yyFlexLexer をリネームします:

           #undef yyFlexLexer
           #define yyFlexLexer xxFlexLexer
           #include <FlexLexer.h>

           #undef yyFlexLexer
           #define yyFlexLexer zzFlexLexer
           #include <FlexLexer.h>

       これはあるスキャナに対し  %option  prefix="xx"   を使用しもう一方に対し
       %option prefix="zz" を使用した場合です。

       重要:  現在のスキャンクラスの形式は  であり、メジャーリリースが変
       わると大きく変更される可能性があります。

LEX および POSIX との非互換性
       flex は AT&T Unix の  lex  ツールのリライトですが(2  つの実装はいかなる
       コードも共有しません)、 いくばくかの拡張と非互換性を持っており、 どちら
       の実装でも受理可能なスキャナを書きたい方は これを意識しなければなりませ
       ん。  flex は POSIX lex 仕様に完全合致しますが、例外は %pointer (デフォ
       ルト)使用と  unput()  呼び出しにより  yytext   の内容を破壊することであ
       り、これは POSIX 仕様に反します。

       この節では、 flex と AT&T lex と POSIX 仕様との間の全ての既知の非互換性
       を扱います。

       flex-l オプションはオリジナルの AT&T lex 実装との最大の互換性を有効
       にしますが、 生成されたスキャナの性能は大きく低下します。 -l オプション
       を使用しても発生しうる非互換性は後で述べます。

       flex は以下の例外を除き lex と完全互換です:

       -      ドキュメントに記載されていない lex  スキャナ内部の変数  yylineno-l  もしくは %option yylineno を使用しないとサポートされませ
              ん。

              yylineno  はスキャナ毎(単一のグローバル変数)ではなく、バッファ毎
              に管理されるべきです。

              yylineno は POSIX 仕様ではありません。

       -      input()  ルーチンは再定義できませんが、 ルールにマッチしたものに
              後続する文字を読むために呼ばれえます。 input()  がファイルの終り
              に到達すると、通常の  yywrap() 処理は終了します。``実際の'' ファ
              イルの終りは EOF として返されます。

              実際には入力は YY_INPUT マクロを定義することにより制御されます。

              input() を再定義できないという flex の制限は、最初に yyin を設定
              する以外のスキャナ入力制御方法を単に規定していないという、 POSIX
              仕様と合致します。

       -      unput() ルーチンは再定義できません。この制限は POSIX  に合致して
              います。

       -      flex スキャナは lex スキャナとは異なりリエントラントではありませ
              ん。 実際、対話的なスキャナにおいて、 割り込みハンドラにてロング
              ジャンプを用いてスキャナから脱出し、  その後スキャナを再度呼び出
              す場合、以下のメッセージを得るでしょう:

                  fatal flex scanner internal error--end of buffer missed

              スキャナに再度入るためには、まず以下のようにして下さい

                  yyrestart( yyin );

              この呼び出しにより入力バッファは捨てられることに注意して下さい;
              通常これは対話的スキャナでは問題ではありません。

              また、C++ スキャナクラスはリエントラント  ので、C++ を使用で
              きるのなら、C++ を使用すべきです。 前述の  "C++  スキャナの生成"
              を参照して下さい。

       -      output()  はサポートされていません。 ECHO マクロからの出力はファ
              イルポインタ yyout  (デフォルトでは    )に対して行われま
              す。

              output() は POSIX 仕様にはありません。

       -      lex  は排他的開始条件 (%x) をサポートしませんが、これは POSIX 仕
              様にあります。

       -      定義を展開する時、 flex では括弧で括ります。 lex では以下は:

                  NAME    [A-Z][A-Z0-9]*
                  %%
                  foo{NAME}?      printf( "Found it\n" );
                  %%

              文字列 "foo" にはマッチしません。 なぜなら展開されたマクロはルー
              ル  "foo[A-Z][A-Z0-9]*?"  と等価になり、  優先度にて `?' は "[A-
              Z0-9]*" と結び付きます。 flex ではルールが展開されると  "foo([A-
              Z][A-Z0-9]*)?" となり、 文字列 "foo" がマッチします。

              ^ で始まるか $ で終る定義は、展開時に括弧で括らず、 これらのオペ
              レータが定義において特別な意味を失わないようにすることに  注意し
              て下さい。 しかし <s>, /, <<EOF>> オペレータは flex の定義では使
              用できません。

              -l を使用すると、 lex の振舞いと同じく定義を括弧で括りません。

              POSIX 仕様では、定義を括弧で括ります。

       -      lex の実装によっては、  ルールのパターンの右側に空白がある場合、
              ルールのアクションを別の行から始めることを許します:

                  %%
                  foo|bar<space here>
                    { foobar_action(); }

              flex はこの機能をサポートしません。

       -      lex%r (Ratfor スキャナの生成)オプションはサポートされていま
              せん。 これは POSIX 仕様には含まれません。

       -      スキャナを %array を使用して構築したのではない限り、 unput()  呼
              び出し後には、次のトークンにマッチするまで yytext は未定義です。
              これは lex にも POSIX 仕様にも当てはまりません。 -l オプションを
              指定するとこの非互換性を取り除きます。

       -      {}  (数値範囲)オペレータの優先度が異なります。 lex は "abc{1,3}"
              を "1 度か 2 度か 3 度の 'abc' にマッチ"  と解釈しますが、  flex
              は  "'ab' に 1 度か 2 度か 3 度の 'c' が続くものにマッチ" と解釈
              します。 後者が POSIX 仕様に合致します。

       -      ^ オペレータの優先度が異なります。 lex は "^foo|bar" を  "行頭の
              'foo'  か任意位置の 'bar' にマッチ" と解釈しますが、 flex は "行
              頭の 'foo' か 'bar' にマッチ" と解釈します。 後者が POSIX 仕様に
              合致します。

       -      lex   でサポートされている  %a  等の特別なテーブルサイズの宣言は
              flex スキャナでは不要です; flex はこれらを無視します。

       -      flexlex   のどちらでもスキャナを使用可能に書けるように、
              FLEX_SCANNER という名前を定義します。 スキャナを生成した flex の
              バージョンを表す YY_FLEX_MAJOR_VERSIONYY_FLEX_MINOR_VERSION
              を、スキャナは含みます  (例えば 2.5 リリースではこれらはそれぞれ
              2 と 5 になります)。

       以下の flex の機能は lex および POSIX 仕様には含まれません:

           C++ スキャナ
           %option
           開始条件スコープ
           開始条件スタック
           対話的/非対話的スキャナ
           yy_scan_string() 等
           yyterminate()
           yy_set_interactive()
           yy_set_bol()
           YY_AT_BOL()
           <<EOF>>
           <*>
           YY_DECL
           YY_START
           YY_USER_ACTION
           YY_USER_INIT
           #line ディレクティブ
           アクションの周りの %{}
           単一行における複数のアクション

       さらにほぼ全ての flex フラグです。 リストの最後の機能の意味は、 flex で
       は複数のアクションをセミコロンで区切って同一行に記述可能ですが、 lex で
       は次の

           foo    handle_foo(); ++num_foos_seen;

       は (驚くべきことに) 次のように切り詰められるということです。

           foo    handle_foo();

       flex はアクションを切り詰めません。  ブレースで括られないアクションは単
       純に行末で終了します。

診断
       warning,  rule cannot be matched 常に同じテキストにマッチするルールが前
       にあるので、 与えられたルールがマッチしません。 例えば以下の  "foo"  は
       "全てを捕まえる" ルールの後ろにありますので 決してマッチしません:

           [a-z]+    got_identifier();
           foo       got_foo();

       スキャナ中で REJECT を使用するとこの警告を抑制します。

       warning,  -s option given but default rule can be matched (おそらくある
       特定の開始条件のもとでは)  デフォルトルール  (任意の一文字にマッチする)
       しか特定の入力に 対してはマッチしないことがあります。 -s を指定している
       ので、おそらくそうなりません。

       reject_used_but_not_detected             undefined             あるいは
       yymore_used_but_not_detected  undefined - これらのエラーは コンパイル時
       に起きます。スキャナが REJECT もしくは yymore()  を使っていますが  flex
       がそのことに気づかなかったということです。  つまり、 flex は最初の 2 つ
       の部分を探しても これらのアクションの出現を見つけられなかったのですが、
       実際には何らかの方法 (例えば #include ファイルを介して)でこれらが記述さ
       れていた、ということです。 %option reject%option  yymore  を使用し
       て、flex にこれらの機能を実際に使用していることを教えて下さい。

       flex  scanner  jammed - -s でコンパイルされたスキャナが、どのルールにも
       マッチしない  入力文字列に遭遇しました。   内部的な問題に起因してこのエ
       ラーが起こることもあります。

       token  too  large,  exceeds YYLMAX - スキャナが %array を使っている場合
       に、あるルールが定数 YYLMAX (デフォルトで 8K バイト) より大きな文字列と
       マッチしました。 flex の入力ファイルの定義部で YYLMAX を #define するこ
       とで値を大きくできます。

       scanner requires -8 flag to use the character 'x' - スキャナの記述に  8
       ビットの文字 'x' を識別する部分があり、 -Cf もしくは -CF のテーブル圧縮
       オプションのためにデフォルトの 7 ビットになっている にもかかわらず、 -8
       オプションをつけていないということです。 詳細は -7 フラグのオプションの
       議論を参照して下さい。

       flex scanner  push-back  overflow  -  unput()  でテキストを戻しすぎたた
       め、スキャナのバッファは 戻したテキストと現トークンを yytext に保てませ
       ん。 この場合、理想的にはスキャナが動的にバッファの大きさを変えるべきで
       すが、 現在のところそうなってはいません。

       input buffer overflow, can't enlarge buffer because scanner uses REJECT
       - スキャナは非常に大きなトークンのマッチを調べていて、入力バッファを 拡
       張する必要が起きました。しかしながら、バッファの拡張は  REJECT を使うス
       キャナでは働きません。

       fatal flex scanner internal error--end of buffer missed -  スキャナが使
       用しているフレームから(を越えて)ロングジャンプした後、   再度スキャナに
       入った場合に起こります。 再度スキャナに入る前に:

           yyrestart( yyin );

       を使うか、前述のように C++ スキャナクラスを使用するようにして下さい。

       too many start conditions in <> construct! - 存在するより多くの開始条件
       を <> 中に記載しました (少なくとも一つを二度記載しました)。

関連ファイル
       -ll    スキャナがリンクしなければならないライブラリ。

       lex.yy.c
              生成されたスキャナ(システムによっては lexyy.c という名前になりま
              す)。

       lex.yy.cc
              -+ を使った時に作成された C++ スキャナクラス。

       <FlexLexer.h>
              C++ スキャナベースクラス FlexLexer とその導出クラス  yyFlexLexer
              を定義するヘッダファイル。

       flex.skl
              スケルトンスキャナ。  このファイルは flex の実行時ではなく、flex
              を構築する時のみ利用されます。

       lex.backup
              -b フラグ用のバックアップ情報(システムによっては lex.bck  という
              名前になります)。

欠陥 / バグ
       右文脈(trailing context)パターンの中には、正しくマッチせず 警告メッセー
       ジ ("dangerous trailing context") を出すものがあります。 これらのパター
       ンは、 ルールの最初の部分が 2番目の頭の部分とマッチするようなものです。
       例えば  "zx*/xy*"  の場合、'x*'  は右文脈の頭の  'x'   とマッチします。
       (POSIX  ドラフトではそのようなパターンにマッチするテキストは 未定義であ
       ると述べていることに注意して下さい。)

       右文脈の中には、実際には固定長であるのにそうとは解釈されないものがあ
       り、  上に述べた性能の低下が起こります。  特に、  '|'  や  {n}  (例えば
       "foo{3}") は常に可変長であると解釈されます。

       右文脈と特別なアクション '|' を組み合わせると  右文脈がよりコスト
       のかかる  右文脈となります。例えば、次のようなものです:

           %%
           abc      |
           xyz/def

       %array もしくは -l オプションを指定しない場合、 unput() を使うと yytext
       と yyleng を破壊します。

       NUL のパターンマッチングは他の文字の比較よりかなり遅くなっています。

       入力バッファの動的な大きさの再調整は時間がかかります。これは現トークン
       (一般に巨大)までのマッチした全テキストの再スキャンを伴うためです。

       入力のバッファリングと先読みのため、  <stdio.h> ルーチンと 混合して使う
       ことが出来ません。例えば、 getchar()flex  のルールはうまく行きませ
       ん。代わりに input() を使って下さい。

       -v  オプションで表示される全テーブルエントリには、 どのルールがマッチし
       たのかを決定するのに必要なテーブルエントリ数が 含まれていません。エント
       リの数はスキャナが  REJECT  を使っていないときには DFA 状態数に等しく、
       使っているときには DFA 状態数よりいくらか大きくなります。

       REJECT がオプション -f もしくは -F とともに使えません。

       flex の内部アルゴリズムについてのドキュメントが必要です。

関連項目
       lex(1), yacc(1), sed(1), awk(1)

       John Levine, Tony Mason, and Doug  Brown,  Lex  &  Yacc,  O'Reilly  and
       Associates.  第 2 版を入手すること。

       M. E. Lesk and E. Schmidt, LEX - Lexical Analyzer Generator

       Alfred  Aho,  Ravi  Sethi  and  Jeffrey  Ullman, Compilers: Principles,
       Techniques and Tools, Addison-Wesley (1986).  flex で使用しているパター
       ンマッチング技法を解説している(決定性オートマトン)。

作者
       Vern   Paxson   が多くのアイディアとインスピレーションを得る助けを  Van
       Jacobson から受けました。 オリジナルバージョンは Jef Poskanzer が作成し
       ました。  高速テーブル表現は Van Jacobson のデザインの部分実装です。 こ
       の実装は Kevin Gong と Vern Paxson が行いました。

       多くの    flex     ベータテスタ、フィードバッカ、コントリビュータ、特に
       Francois  Pinard, Casey Leedom, Robert Abramovitz, Stan Adermann, Terry
       Allen, David Barker-Plummer, John  Basrai,  Neal  Becker,  Nelson  H.F.
       Beebe,  benson@odi.com,  Karl  Berry,  Peter A. Bigot, Simon Blanchard,
       Keith Bostic, Frederic Brehm, Ian Brockbank, Kin Cho, Nick Christopher,
       Brian  Clapper,  J.T.  Conklin, Jason Coughlin, Bill Cox, Nick Cropper,
       Dave Curtis, Scott David Daniels, Chris  G.  Demetriou,  Theo  Deraadt,
       Mike  Donahue,  Chuck  Doucette,  Tom Epperly, Leo Eskin, Chris Faylor,
       Chris Flatters, Jon Forrest, Jeffrey Friedl, Joe Gayda, Kaveh R. Ghazi,
       Wolfgang Glunz, Eric Goldman, Christopher M. Gould, Ulrich Grepel, Peer
       Griebel, Jan Hajic, Charles Hemphill, NORO  Hideo,  Jarkko  Hietaniemi,
       Scott  Hofmann,  Jeff  Honig, Dana Hudes, Eric Hughes, John Interrante,
       Ceriel Jacobs, Michal Jaegermann, Sakari Jalovaara, Jeffrey  R.  Jones,
       Henry  Juengst, Klaus Kaempf, Jonathan I. Kamens, Terrence O Kane, Amir
       Katz, ken@ken.hilco.com, Kevin B. Kenny, Steve Kirsch, Winfried Koenig,
       Marq  Kole, Ronald Lamprecht, Greg Lee, Rohan Lenard, Craig Leres, John
       Levine, Steve Liddle, David Loffredo, Mike Long, Mohamed el Lozy, Brian
       Madsen,  Malte,  Joe  Marshall,  Bengt  Martensson, Chris Metcalf, Luke
       Mewburn, Jim Meyering, R. Alexander Milowski, Erik Naggum, G.T.  Nicol,
       Landon  Noll,  James  Nordby,  Marc  Nozell,  Richard  Ohnemus, Karsten
       Pahnke, Sven Panne, Roland Pesch,  Walter  Pelissero,  Gaumond  Pierre,
       Esmond   Pitt,   Jef  Poskanzer,  Joe  Rahmeh,  Jarmo  Raiha,  Frederic
       Raimbault, Pat Rankin, Rick Richardson, Kevin Rodgers, Kai Uwe  Rommel,
       Jim  Roskind,  Alberto  Santini, Andreas Scherer, Darrell Schiebel, Raf
       Schietekat, Doug Schmidt, Philippe Schnoebelen, Andreas  Schwab,  Larry
       Schwimmer,  Alex  Siegel,  Eckehard  Stolz,  Jan-Erik  Strvmquist, Mike
       Stump, Paul Stuart, Dave Tallman,  Ian  Lance  Taylor,  Chris  Thewalt,
       Richard  M. Timoney, Jodi Tsai, Paul Tuinenga, Gary Weik, Frank Whaley,
       Gerhard Wilhelms, Kent Williams, Ken Yap,  Ron  Zellar,  Nathan  Zelle,
       David Zuhn, および私の最低のメールアーカイブ能力から滑り落ちた方々、 そ
       れらの方々の協力にも同様に感謝します。

       Keith Bostic, Jon Forrest, Noah Friedman, John  Gilmore,  Craig  Leres,
       John  Levine,  Bob  Mulcahy,  G.T.   Nicol, Francois Pinard, Rich Salz,
       Richard Stallman には多くの悩みの分散に関して感謝します。

       Esmond Pitt と Earle Horton には 8  ビット文字サポートに関して;  Benson
       Margulies と Fred Burke には C++ サポートに関して; Kent Williams と Tom
       Epperly には C++ クラスサポートに関して; Ove Ewerlid には NUL  のサポー
       トに関して;  Eric Hughes には複数バッファのサポートに関して、それぞれ感
       謝します。

       この作品は当初、私が CA Berkeley の Lawrence Berkeley Laboratory におけ
       る  Real Time Systems Group にいた時に作成されました。 私に協力してくれ
       た方々に感謝します。

       コメントは vern@ee.lbl.gov に送って下さい。