lex(1) FreeBSD 一般コマンドマニュアル

lex

前のページ 上に戻る 次のページ

lex



書式

       flex  [-bcdfhilnpstvwBFILTV78+? -C[aefFmr] -ooutput -Ppre-
       fix -Sskeleton] [--help --version] [filename ...]


概説

       本マニュアルは、テキストのパターンマッチングを行うプログラ
       ムを生成するツール flex を扱います。本マニュアルはチュート
       リアルとリファレンス節とを含みます:

           解説
               ツールの短い概説

           簡単な例

           入力ファイルのフォーマット

           パターン
               flex が使用する拡張した正規表現

           入力のマッチ方法
               何がマッチするかを決定する規則

           アクション
               パターンがマッチした時に何を行うかを指定する方法

           生成されたスキャナ
               flex が生成するスキャナに関する詳細;
               入力元の制御方法

           開始条件
               スキャナへの文脈の導入と、
               "ミニスキャナ" の制御方法

           複数の入力バッファ
               複数の入力元を扱う方法;
               ファイルではなく文字列からスキャンする方法

           ファイルの終りのルール
               ファイルの終りにマッチする特別なルール

           雑多なマクロ
               アクションで使用可能なマクロのまとめ

           ユーザが使用可能な値
               アクションで使用可能な値のまとめ

           Yacc とのインタフェース
               lex スキャナと yacc パーサとの結合

           オプション
               flex のコマンドラインオプションと、
               "%option" ディレクティブ
               エラーメッセージで意味が明確でないもの

           関連ファイル
               flex が使用するファイル

           欠陥 / バグ
               flex の既知の問題

           関連項目
               ツールに関係する他のドキュメント

           作者
               連絡方法を含みます



解説

       flex は スキャナを生成するためのツールです。ここで、スキャ
       ナとは、テキスト内の字句パターンを解析するプログラムです。
       flex は指定したファイル、もしくはファイル名が与え ら れ な
       かった場合は標準入力から、生成するスキャナの記述を読み込み
       ます。この記述は、正規表現と C コードのペアの形をとって い
       ます。これは ルールと呼ばれます。 flex は、出力として C ソ
       ースファイルの lex.yy.c を生成しますが、その中 に  yylex()
       ルーチンが定義されます。このファイルはコンパイルされ、 -ll
       ライブラリとともにリンクされて、実行形式となります。実行形
       式が走り始めると、正規表現をマッチさせるために入力が解析さ
       れます。マッチするものを見つけると、対応する C コードが 実
       行されます。


簡単な例

       ま ず 簡単な例から、 flex の使い方を見て行きましょう。次の
       flex の入力は、"username" という文字列に出会うとユーザのロ
       グイン名に置き換えるスキャナを指定しています:

           %%
           username    printf( "%s", getlogin() );

       デフォルトでは、 flex スキャナにマッチしなかったテキストは
       出力にコピーされますので、 "username" を展開しながら入力を
       出 力 にコピーすることがこのスキャナの最終的な結果となりま
       す。この入力にはただ一つのルールだけがあり ま す。  "user-
       name" は パターンであり、"printf" は アクションです。 "%%"
       はルールの始まりの印です。

       別の例を見て見ましょう:

           %{
                   int num_lines = 0, num_chars = 0;
           %}

           %%
           \n      ++num_lines; ++num_chars;

       チンからアクセス可能です。ここには 2 つのルールが あ り ま
       す。  1 つ目は改行文字 ("\n") にマッチし、行数と文字数のカ
       ウントを増加させます。もう 1 つは、改行文字以外の全ての 文
       字 ("." という正規表現で表されています)にマッチします。

       次はもうちょっと複雑な例です:

           /* scanner for a toy Pascal-like language */

           %{
           /* need this for the call to atof() below */
           #include <math.h>
           %}

           DIGIT    [0-9]
           ID       [a-z][a-z0-9]*

           %%

           {DIGIT}+    {
                       printf( "An integer: %s (%d)\n", yytext,
                               atoi( yytext ) );
                       }

           {DIGIT}+"."{DIGIT}*        {
                       printf( "A float: %s (%g)\n", yytext,
                               atof( yytext ) );
                       }

           if|then|begin|end|procedure|function        {
                       printf( "A keyword: %s\n", yytext );
                       }

           {ID}        printf( "An identifier: %s\n", yytext );

           "+"|"-"|"*"|"/"   printf( "An operator: %s\n", yytext );

           "{"[^}\n]*"}"     /* eat up one-line comments */

           [ \t\n]+          /* eat up whitespace */

           .           printf( "Unrecognized character: %s\n", yytext );

           %%

           main( argc, argv )
           int argc;
           char **argv;
               {
               ++argv, --argc;  /* skip over program name */
               if ( argc > 0 )
                       yyin = fopen( argv[0], "r" );

       行により分けられます:

           定義
           %%
           ルール
           %%
           ユーザコード

       定義部分は、スキャナの宣言を単純化する単純な 名前の定義 の
       宣言と、後で説明する 開始条件の宣言とからなります。

       名前の定義は次の形式です:

           名前 定義

       "名前" は語であり、レターかアンダースコア ('_') から始まっ
       て 0 個以上のレター・数字・'_'・'-' (ダッシュ)が続きます。
       定義は、名前に続く最初の非空白文字から始まり、行末まで続く
       ものとされます。定義は後で "{名前}" で参照でき、"( 定 義)"
       を展開します。例えば、

           DIGIT    [0-9]
           ID       [a-z][a-z0-9]*

       は、  "DIGIT" が単一の数字にマッチする正規表現であると定義
       し、 "ID" がレターに 0 個以上のレターか数字が続く正規表 現
       であると定義します。後で出て来る参照

           {DIGIT}+"."{DIGIT}*

       は

           ([0-9])+"."([0-9])*

       と同じであり、1 個以上の数字に '.' が続き、 0 個以上の数字
       が続くものにマッチします。

       flex の入力の ルールは次の形式の一連のルールからなります:

           パターン   アクション

       ここで、パターンはインデントされていてはならず、アクション
       は同じ行から始まる必要があります。

       パターンとアクションの詳細は後の解説を見て下さい。

       最 後に、ユーザコードの部分は単純にそのままの形で lex.yy.c
       にコピーされます。スキャナを呼び出すまたは呼び出される付随
       ルーチンのために使用されます。この部分はあっても無くても構
       いません; 無い場合には、入力ファイル中の 2 番目の %% も 省
       略できます。

       定義の部分(ルールの部分ではないです)では、インデントされて
       いないコメント("/*" から始まる行) は次の "*/" までそのまま
       の形でコピーされます。


パターン

       入 力 ファイルのパターンは拡張した正規表現を使って記述しま
       す。以下に示します:

           x          文字 'x' にマッチ。
           .          改行を除く全ての文字(バイト)。
           [xyz]      "文字クラス"; この場合、'x', 'y', 'z' のいずれにも
                        マッチします。
           [abj-oZ]   範囲指定を含む "文字クラス"; この場合、'a', 'b' と
                        'j' から 'o' までの任意のレターと 'Z' にマッチします。
           [^A-Z]     "否定文字クラス"; クラスに含まれない任意の文字に
                        マッチします。 この場合、'A' から 'Z' までの大文字
                        「以外の」文字にマッチします。
           [^A-Z\n]   大文字と改行を「除く」全ての文字。
           r*         0 もしくはそれ以上の r。r は任意の正規表現。
           r+         1 もしくはそれ以上の r。
           r?         0 もしくは 1つの r (「おまけ」の r)
           r{2,5}     2 つから 5つまでの r。
           r{2,}      2 つ以上の r。
           r{4}       ちょうど 4つ の r。
           {名前}     "名前" の定義の展開。
                      (上を参照)
           "[xyz]\"foo"
                      文字列 [xyz]"foo
           \X         X が 'a', 'b', 'f', 'n', 'r', 't', 'v' のいずれかの
                        とき、ANSI-C での \X の解釈となります。
                        それ以外の場合、文字 'X' ('*' のようなオペレータの
                        意味を打ち消し、その文字自体を指定する際に使います)。
           \123       8進数で 123 と表される文字。
           \x2a       16進数で 2a と表される文字。
           (r)        r にマッチ; ()は 優先順位を変えるために使用。
                        (以下を参照)


           rs         正規表現 r に正規表現 s が続く; 「連結(concatenation)」
                        と呼びます。


           r|s        r もしくは s。


           r/s        後ろに s が続く時の r。
                        s にマッチするテキストはこのルールの "最長適合" を判定する
                        時には含まれますが、アクションが実行される前に
                        入力に戻されます。
                        アクションは r にマッチするテキストだけを見ます。
                        このパターンは "右文脈(trailing context)" と呼ばれます。
                        (flex が正確にマッチ不能な r/s の組合せは複数あります;

           <s>r       開始条件 s における r。(開始条件については以下を
                      参照)。
           <s1,s2,s3>r
                      上に同じ。ただし開始条件は s1, s2, s3 のいずれでもよい。
           <*>r       任意の開始条件の r。開始条件は排他的なものでもよい。


           <<EOF>>    ファイルの終了。
           <s1,s2><<EOF>>
                      開始条件が s1 もしくは s2 であるときのファイルの終了。

       文字クラス中では、全ての正規表現のオペレータは、エスケープ
       ('\') および文字クラスオペレータである '-' と ']' とクラス
       の先頭の '^' を除き特別な意味を失うことに注意して下さい。

       上に挙げた正規表現は優先順位によってグループに分けられてい
       ます。一番上のグループが最も高い優先度で、一番下のグループ
       の優先順位が最も低くなっています。グループ内では同じ優先順
       位です。例えば、

           foo|bar*

       は

           (foo)|(ba(r*))

       と 同 じ です。なぜなら '*' オペレータは連結より優先度が高
       く、連結は選言 ('|') より優先度が高いからです。このパタ ー
       ン は文字列 "foo" もしくは文字列 "ba" に 0 個以上の r がつ
       づくものの どちらにもマッチします。 "foo" もしくは 0 個 以
       上の "bar" にマッチさせるためには次の表現を使用して下さい:

           foo|(bar)*

       0 個以上の "foo" または "bar" にマッチするためには次の表現
       を使用して下さい:

           (foo|bar)*


       文 字もしくは文字範囲に加え、文字クラスも文字クラスの 表現
       を含みます。これらの表現は [: および :] のデリミタに囲まれ
       ま す  (文字クラスの '[' と ']' との間に現れる必要がありま
       す; 他の要素が文字クラス中に現れても構いません)。有効な 表
       現は以下の通りです:

           [:alnum:] [:alpha:] [:blank:]
           [:cntrl:] [:digit:] [:graph:]
           [:lower:] [:print:] [:punct:]
           [:space:] [:upper:] [:xdigit:]

       これらの表現は対応する標準 C の isXXX 関数に適合する全ての

       パターンに関する注意点です:

       -      否定文字クラス、例えば上の "[^A-Z]" は "\n" (もしく
              は これを表すエスケープシーケンス) が明示的に否定文
              字クラスに現れている場合 (例えば "[^A-Z\n]") を除き
              改 行にマッチします。これは他の正規表現ツールが否定
              文字クラスを扱う方法とは異なりますが、不幸なこと に
              こ の矛盾は歴史的に確立しています。改行にマッチする
              とは、入力に別のクオートが存在しない場合に [^"]* の
              よ うなパターンが入力全体にマッチすることを意味しま
              す。

       -      ルールは右文脈('/' オペレータもしくは '$' オペレ ー
              タ)   を 高 々 一 つしか持てません。開始条件 '^' と
              "<<EOF>>" パターンはパターンの最初になけれ ば な ら
              ず、  '/',  '$'  同様に () 内にいれることは出来ませ
              ん。ルールの先頭ではない '^' もしくはルールの終りで
              はない '$' は特別な意味を失い、通常の文字として扱わ
              れます。

              以下は無効です:

                  foo/bar$
                  <sc1>foo<sc2>bar

              前者は "foo/bar\n" と書けます。

              以下では '$' と '^' とは通常の文字として扱われます:

                  foo|(bar$)
                  foo|^bar

              "foo"   も しくは "改行が続く bar" を指定したい場合
              は、次の表現を使用して下さい (特別な '|' の動作は後
              で説明します):

                  foo      |
                  bar$     /* action goes here */

              同 じ 方 法で、foo もしくは 行頭の bar を指定可能で
              す。


入力のマッチ方法

       生成したスキャナを実行すると、スキャナは入力を見てパターン
       に マッチする文字列を探します。 1 より多くのマッチを見付け
       ると、最長テキストのマッチを採用します ( 右 文 脈(trailing
       context  rule)の後ろの部分も長さに含みますが、後ろの部分は
       入力に戻されます)。同じ長さのマッチを 2 つ以上見付け た 場
       合、  flex  入力ファイルで最初に記述されたルールを採用しま
       す。

       キャナを生成します。

       yytext は 2 つの異なった方法により定義されうることに注意し
       て下さい: 文字 ポインタもしくは文字 配列です。 flex がどち
       らの定義を使用するかは特別なディレクティブ %pointer もしく
       は %array を flex の入力の最初の(定義)部分に含めることによ
       り制御できます。デフォルトは %pointer であり、 -l lex 互換
       オプションを使用した場合には例外的に yytext は配列になりま
       す。 %pointer を使用する利点はスキャンが高速であること、非
       常に大きなトークンにマッチする時にも (動的メモリを使用し尽
       くさない限り)バッファオーバフローとならないことです。欠 点
       は、 アクションが yytext を修正することが制限されること(次
       節参照)、 unput() 呼び出しが yytext の現在の内容を破壊する
       こ とです。これは異なる lex バージョン間での移植性に関する
       頭痛の種です。

       %array の利点は yytext の内容を思った通りに変更で き る こ
       と、  unput() を呼び出しても yytext の内容が破壊されないこ
       とです(下記参照)。その上、既存の lex プログラム は  yytext
       を外部から次の形式の宣言を使用してアクセスしていることがあ
       ります:
           extern char yytext[];
       この定義は %pointer 使用時には誤りですが、 %array 使用時に
       は正しいです。

       %arrayyytext を文字数 YYLMAX (デフォルトは十分大きな
       値)の配列であると定義します。この大きさは、 flex の入力 の
       最 初の部分で単純に YYLMAX を異なった値に #define すること
       により変更できます。上記の通り、 %pointer   使 用 時 に は
       yytext  は大きなトークンを格納するために動的に大きくなりま
       す。このことは %pointer を使用したスキャナは非常に大きなト
       ー クン (例えばコメントブロック全体)を格納可能であることを
       意味しますが、スキャナが yytext の大きさを変えるたびにトー
       クン全体を先頭から再スキャンすることが必要となるためこのよ
       うなトークンに対するマッチングは遅くなりうることを覚えてお
       い て下さい。現在、 yytextunput() が結果として返すテキ
       ストが大きい時には動的には大きくなり ません; 実行時エラ ー
       となります。

       ま た、 %array は C++ スキャナクラスでは使用できないことに
       注意して下さい( c++ オプションに関しては下記参照)。


アクション

       ルール中のパターンは対応するアクションを持ちます。アクショ
       ン は任意の C の文です。パターンは最初のエスケープされてい
       ない空白文字で終ります; 行の残りがアクションです。アクショ
       ンが空である場合、パターンがマッチした時に入力トークンは単
       純に捨てられます。例えば入力から全ての "zap me" を削除する
       プログラムの仕様を示します:

           %%
           "zap me"

       びコメントに関して知っており、それらの中のブレースを誤解す
       ることはありませんが、アクションが %{ で始まることを許し、
       次の %} までのテキストがアクションであるとします (アクショ
       ン内部の任意個のブレースには関係ありません)。

       垂直バー ('|') のみからなるアクションは "次のルールと同じ"
       を意味します。説明は以下を見て下さい。

       ア ク ショ ンは任意の C コードを含むことが出来ます。これに
       は、 yylex() を呼び出したルーチンに対して値を返 す  return
       文 も含まれます。 yylex() が呼ばれるたび、最後に残ったトー
       クンから処理を再開し、ファイルの終了もしくは return を実行
       するまで処理を行います。

       アクションは自由に yytext を変更できますが、例外は長さを増
       やすことです (文字を末尾に加えることになり、これは入力スト
       リ ームの後続する文字を上書きします)。これは %array 使用時
       には当てはまりません(上述); この場合 yytext を自由に変更で
       きます。

       ア ク ションは自由に yyleng を変更できますが、アクションが
       yymore() を使用する時には例外的に変更してはいけませ ん( 後
       述)。

       多くの特別なディレクティブがあり、アクション中に含めること
       が出来ます:

       -      ECHO yytext をスキャナの出力にコピーします。

       -      BEGIN 後ろに開始条件の名前を書くと、スキャナを対 応
              する開始条件に設定します(後述)。

       -      REJECT  入力(もしくは入力の頭)に "2 番目によく(sec-
              ond best)" マッチするルールに進むようにスキャナに指
              示 します。 "入力のマッチ方法" で示したようにルール
              は選択され、 yytextyyleng は適切に設定 さ れ ま
              す。 選択されるルールは、最初に選択されたルールと同
              じ長さであるが flex の入力ファイルにて後で出て来 る
              も の、もしくは少ない文字数にマッチするものです。例
              えば次の例では入力中の語を数え、 "frob" が見付か る
              たびにルーチン special() を呼びます:

                          int word_count = 0;
                  %%

                  frob        special(); REJECT;
                  [^ \t\n]+   ++word_count;

              REJECT が無い場合、入力中の "frob" は語として数えら
              れず、スキャナは通常通りトークン毎に 1 つのアクショ
              ン だけを行います。複数の REJECT を使用可能であり、
              それぞれ現在有効なルールの次に良い選択を見 付 け ま
              の いずれかにでも REJECT が使われたなら、スキャナの
              全 てのマッチング速度を低下させるということです。さ
              らに REJECT をオプション -Cf-CF と共に用いる こ
              とは出来ません。

              ま た、 他 の 特 別 ア ク ションと違い REJECT は 分
              岐(branch) であることに注意してください; すな わ ち
              REJECT 直後のアクションは実行 されません。

       -      yymore() 次にルールとマッチしたときには、対応するト
              ークンは、現在の yytext の内容と入れ換えるのでは な
              く yytext に 追加するようスキャナに指示します。例え
              ば、入力 "mega-kludge" が与えら れ る と、 以 下 は
              "mega-mega-kludge" を出力に書きます:

                  %%
                  mega-    ECHO; yymore();
                  kludge   ECHO;

              最初の "mega-" はマッチし出力にエコーされます。次に
              "kludge" がマッチしますが、直前の "mega-"  が ま だ
              yytext  の先頭に残っており、"kludge" の ECHO ルール
              は実際には "mage-kludge" を書きます。

       yymore() の使用に関し 2 つの注意点が あ り ま す。 ま ず、
       yymore()  は現在のトークンの大きさを反映する yyleng の値の
       正確さに依存することであり、 yymore() 使用時には yyleng を
       変 更 し て は な り ま せん。次に、スキャナのアクションに
       yymore() があると、スキャナのマッチ速度に若干悪影響があ り
       ます。

       -      yyless(n) 現在のトークンから最初の n 文字を除いたも
              のを入力ストリームに戻します。戻した文字列はス キャ
              ナ が 次 のマッチングをとるときに再度スキャンされま
              す。 yytextyyleng は適切に調整されます(例 え ば
              yylengn となります)。例えば、入力 "foobar" が与
              えられると、以下は "foobarbar" を書きます:

                  %%
                  foobar    ECHO; yyless(3);
                  [a-z]+    ECHO;

              引数 0 を yyless に与えると、現在の入力文字列全体が
              再 度スキャンされます。 (例えば BEGIN を使用して)次
              にスキャナが入力する方法を変更していないと、無限 ル
              ープとなります。

       yyless はマクロであり、flex 入力ファイルでのみ使用可能であ
       り、別のソースファイルからは使用不能であることに注意して下
       さい。

       -      unput(c)  文字 c を入力ストリームへ戻します。戻した

              unput() は文字を入力ストリームの 先頭に戻すので、文
              字 列を戻す場合には後ろから前に向かって戻す必要があ
              ります。

       unput() 使用時の重要な潜在的な問題は、 %pointer 使用時( デ
       フォ ル ト)に unput() を呼び出すと、右端の文字から開始し 1
       文字ずつ左に向かって消費され、 yytext の内容が 破壊され る
       ことです。 (上記例のように) unput() 呼び出し後も yytext の
       内容を保存するためには、始めに別の場所にコピーする か、 ス
       キャ ナを %array を使うように構築することです(入力のマッチ
       方法参照)。

       最後に、 EOF を戻して入力ストリームにファイルの終りをマ ー
       クするとは出来ないことに注意して下さい。

       -      input()  次の文字を入力ストリームから読みます。次の
              例は C コメントを食べます:

                  %%
                  "/*"        {
                              register int c;

                              for ( ; ; )
                                  {
                                  while ( (c = input()) != '*' &&
                                          c != EOF )
                                      ;    /* eat up text of comment */

                                  if ( c == '*' )
                                      {
                                      while ( (c = input()) == '*' )
                                          ;
                                      if ( c == '/' )
                                          break;    /* found the end */
                                      }

                                  if ( c == EOF )
                                      {
                                      error( "EOF in comment" );
                                      break;
                                      }
                                  }
                              }

              (スキャナが C++ でコンパイルされたときは、このル ー
              チ ンは yyinput() という名称になり、 C++ ストリーム
              の input と名前が衝突することを避けます。)

       -      YY_FLUSH_BUFFER スキャナの内部バッファをフラッ シュ
              し、 次 に スキャナがトークンをマッチしようとした時
              バッファを YY_INPUT にてリフィルします(生成されたス

       ブルと、複数の付属ルーチンとマクロからなります。デフォルト
       では、 yylex() は次のように宣言されます:

           int yylex()
               {
               ... various definitions and the actions in here ...
               }

       ( 環 境 が 関 数 プロトタイプをサポートしている場合、 "int
       yylex( void )" となります。) この定義は "YY_DECL" マクロを
       定義することにより変更できます。例えば次のように使用するこ
       とが出来ます:

           #define YY_DECL float lexscan( a, b ) float a, b;

       これはスキャンルーチンの名前を lexscan とし、浮動小数点 数
       を 返すようにし、2 つの浮動小数点数を引数とします。 K&R の
       非プロトタイプの関数宣言を使用してスキャンルーチンに対して
       引 数を与える場合、定義をセミコロン(;)で終了する必要があり
       ます。

       yylex() は呼ばれるたび、グローバル入力ファイル  yyin  ( デ
       フォ ルトでは標準入力)からトークンをスキャンします。ファイ
       ルの終りになる(この場合 0 を返します)か、 ア ク ショ ン が
       return 文を実行するまで、実行を続けます。

       スキャナがファイルの終りに到達すると、 yyin が新たなファイ
       ルを指さないか (新たなファイルを指す場合はこのファイルのス
       キャンを続けます)、 yyrestart() が呼ばれない限り、後続する
       呼び出しは未定義です。 yyrestart()FILE *  ポ イ ン タ(
       YY_INPUT  を設定して yyin 以外のソースをスキャンするように
       した場合には nil も可です) である引数を 1 つとり、そのファ
       イルからのスキャンのために yyin を初期化します。本質的に、
       yyin を新しい入力ファイルに割り当てることと yyrestar()  を
       使用することとは同じです; 後者は前のバージョンの flex との
       互換性のために使用可能であり、またスキャンの途中で入力ファ
       イルを変えることが可能です。引数を yyin として呼び出すこと
       により、現在の入力バッファを捨てることも出来ます; ただし、
       YY_FLUSH_BUFFER (上述)を使用する方が良いです。 yyrestart()INITIAL の開始条件を変更し ないことに注意して下さい (後
       述の開始条件参照)。

       あ る アクション中で return 文を実行することにより yylex()
       がスキャンを止めた場合、スキャナは再度呼び出し可能であり、
       この場合スキャンの残りの部分から再開します。

       デフォルトで(効率のため)、スキャナは単純な getc() コールで
       はなくブロックリードを行い、 yyin から文字を読みます。入力
       取 得 方法は YY_INPUT マクロを定義することにより制御できま
       す。    YY_INPUT       呼   び   出   し    手    順    は
       "YY_INPUT(buf,result,max_size)"   です。このアクションは、
       buf 文字配列中に最大 max_size 文字を用 意 し、 整 数 変 数
       この定義により、入力処理は 1 度に 1 文字ずつ行うように変更
       されます。

       スキャナが YY_INPUT からファイルの終りを通知された場合、ス
       キャ ナ は yywrap() 関数をチェックします。 yywrap() 関数が
       偽(ゼロ)を返す場合、関数は続行中であるとされ、 yyin を別の
       入力ファイルを指すように設定し、スキャンを続行します。関数
       が真(非ゼロ)を返す場合、スキャナは終了し、呼び出し元 に  0
       を返します。どちらの場合も開始条件は変化しないことに注意し
       て下さい; つまり INITIAL には戻り ません。

       独自の yywrap() を設定しない場合、 %option noyywrap (こ の
       場合スキャナは yywrap() が 1 を返したかのように動作します)
       を使用するか、フラグ -ll を指定してデフォルトのルーチン(常
       に 1 を返します)を使用しなければなりません。

       ファイルではなくメモリ中のバッファからスキャンするための 3
       つ の ル ー チ ン を 使 用 可 能 で す:  yy_scan_string(),
       yy_scan_bytes(), yy_scan_buffer() 。これらに関する議論は複
       数の入力バッファの節を参照して下さい。

       スキャナは、自己の ECHO 出力を yyout グローバル(デフォルト
       では標準出力であり、別の FILE ポインタに割り当てることで再
       定義できます)に書きます。


開始条件

       flex は、条件的に有効となるルールのための機構を提 供 し ま
       す。 パ ターンのプレフィックスが "<sc>" となっているルール
       は、スキャナが "sc" という名前の開始条件にいる場合のみ有効
       です。例えば、

           <STRING>[^"]*        { /* eat up the string body ... */
                       ...
                       }

       はスキャナが "STRING" 開始条件にいる時のみ有効であり、

           <INITIAL,STRING,QUOTE>\.        { /* handle an escape ... */
                       ...
                       }

       は現在の開始条件が、 "INITIAL", "STRING", "QUOTE" のいずれ
       かの場合のみ有効です。

       開始条件は、入力の定義(先頭)部において、インデントされない
       行で %s もしくは %x から始まり名前が続く行において宣言され
       ます。前者は 内包的開始条件を、後者は 排他的開始条件を、そ
       れ ぞれ宣言します。開始条件を有効にするのは BEGIN アクショ
       ンです。次の BEGIN アクションが実行されるまで、与えられ た
       開始条件のルールは有効であり、他の開始条件のルールは無効で
       す。開始条件が 内包的な場合、開始条件を持たないルールも ま
       た 有効です。開始条件が 排他的な場合、開始条件を満たすルー
           bar            something_else();

       は

           %x example
           %%

           <example>foo   do_something();

           <INITIAL,example>bar    something_else();

       と 等価です。 <INITIAL,example> が無いと、2 番目の例におけ
       る bar パターンは、開始条件が example の場合、有効となりま
       せん(すなわちマッチしません)。 <example> だけを bar につけ
       ると、 example だけにおいて有効となり、 INITIAL では有効と
       なりません。一方、最初の例ではどちらの場合でも有効です。な
       ぜなら最初の例では example 開始条件は 内包的 (%s) 開始条件
       だからです。

       特 殊な開始条件指定子 <*> は全ての開始条件にマッチすること
       に注意して下さい。このため、上の例は次のようにも書けます;

           %x example
           %%

           <example>foo   do_something();

           <*>bar    something_else();


       デフォルトルール(マッチしなかった文字に対しては ECHO です)
       は開始条件中でも有効です。これは次のものと等価です:

           <*>.|\n     ECHO;


       BEGIN(0)  は、開始条件の無いルールだけが有効である、最初の
       状態に戻ります。この状態は開始条件 "INITIAL" として参照 で
       きるため、 BEGIN(INITIAL)BEGIN(0) と等価です。 (開始条
       件名を括る括弧は不要ですが、良いスタイルであるとされていま
       す。)

       BEGIN アクションは、ルール部の先頭のインデントされたコード
       中に現れても良いです。例えば以下の例では、 yylex() が呼 ば
       れ グローバル変数 enter_special が真の場合には、スキャナは
       "SPECIAL" 開始条件に入ります:

                   int enter_special;

           %x SPECIAL
           %%
                   if ( enter_special )

           #include <math.h>
           %}
           %s expect

           %%
           expect-floats        BEGIN(expect);

           <expect>[0-9]+"."[0-9]+      {
                       printf( "found a float, = %f\n",
                               atof( yytext ) );
                       }
           <expect>\n           {
                       /* that's the end of the line, so
                        * we need another "expect-number"
                        * before we'll recognize any more
                        * numbers
                        */
                       BEGIN(INITIAL);
                       }

           [0-9]+      {
                       printf( "found an integer, = %d\n",
                               atoi( yytext ) );
                       }

           "."         printf( "found a dot\n" );

       次は、C のコメントを理解(して捨てる)一方で、現在の入力行を
       数えるスキャナです。

           %x comment
           %%
                   int line_num = 1;

           "/*"         BEGIN(comment);

           <comment>[^*\n]*        /* eat anything that's not a '*' */
           <comment>"*"+[^*/\n]*   /* eat up '*'s not followed by '/'s */
           <comment>\n             ++line_num;
           <comment>"*"+"/"        BEGIN(INITIAL);

       このスキャナは各ルールで可能な最大のテキストにマッチしよう
       とする場合、ちょっとした問題が起こります。一般的には、高速
       なスキャナを記述する場合、各ルールで最大のマッチを得ようと
       することが最も成功します。

       開始条件名は実際には整数値であり、格納することが出来ること
       に注意して下さい。そのため、上記例は以下のように拡張できま
       す:

           %x comment foo
           %%

           <comment>[^*\n]*        /* eat anything that's not a '*' */
           <comment>"*"+[^*/\n]*   /* eat up '*'s not followed by '/'s */
           <comment>\n             ++line_num;
           <comment>"*"+"/"        BEGIN(comment_caller);

       さらに、現在の開始条件を整数値であるマクロ YY_START にてア
       クセスできます。例えば、上記の comment_caller への代入は次
       のように記述できます。

           comment_caller = YY_START;

       flex   は YYSTATEYY_START のエイリアスとして提供します
       (AT&T の lex が使用しています)。

       開始条件は独自の名前空間を持たないことに注意して下さい; %s
       や %x の宣言における名前宣言の扱いは #define と同じです。

       最後に、排他的開始条件を使用する、展開されたエスケープシー
       ケンスを含む(長すぎる文字列のチェックは含みません) C ス タ
       イルのクオート文字列へのマッチ方法を示します:

           %x str

           %%
                   char string_buf[MAX_STR_CONST];
                   char *string_buf_ptr;


           \"      string_buf_ptr = string_buf; BEGIN(str);

           <str>\"        { /* saw closing quote - all done */
                   BEGIN(INITIAL);
                   *string_buf_ptr = '\0';
                   /* return string constant token type and
                    * value to parser
                    */
                   }

           <str>\n        {
                   /* error - unterminated string constant */
                   /* generate error message */
                   }

           <str>\\[0-7]{1,3} {
                   /* octal escape sequence */
                   int result;

                   (void) sscanf( yytext + 1, "%o", &result );

                   if ( result > 0xff )
                           /* error, constant is out-of-bounds */

           <str>\\f  *string_buf_ptr++ = '\f';

           <str>\\(.|\n)  *string_buf_ptr++ = yytext[1];

           <str>[^\\\n\"]+        {
                   char *yptr = yytext;

                   while ( *yptr )
                           *string_buf_ptr++ = *yptr++;
                   }


       上記例のように同一の開始条件を持つ全てのルールの前に開始条
       件を書かねばならないことが多いです。 flex はこれを簡単かつ
       綺 麗にするため開始条件 スコープを導入しました。開始条件ス
       コープは次のように始まります:

           <SCs>{

       ここで SCs は 1 つ以上の開始条件のリストです。開始条件スコ
       ープ内では、最初の '{' にマッチするまでの '}' において、全
       てのルールは自動的に <SCs> のプレフィックスが付きます。 そ
       のため、例えば

           <ESC>{
               "\\n"   return '\n';
               "\\r"   return '\r';
               "\\f"   return '\f';
               "\\0"   return '\0';
           }

       は次のものと等価です:

           <ESC>"\\n"  return '\n';
           <ESC>"\\r"  return '\r';
           <ESC>"\\f"  return '\f';
           <ESC>"\\0"  return '\0';

       開始条件スコープはネストすることが出来ます。

       開 始条件のスタックを制御するために 3 つのルーチンを使用可
       能です:

       void yy_push_state(int new_state)
              現在の開始条件を開始条件スタックの先頭 に プッ シュ
              し、 BEGIN new_state を使用したかのように new_state
              に切り替えます (開始条件名は整数値でもあることを 思
              い出して下さい)。

       void yy_pop_state()
              スタックの先頭をポップし、 BEGIN を使用してその開始
              条件に切り替えます。

       ス キャナによっては(ファイルの "include" をサポートする等)
       複数の入力ストリームを扱う必要があります。 flex スキャナで
       は大きなバッファリングを行うため、スキャンコンテキストに影
       響される YY_INPUT を単純に書き換えるだけでは次の入力がどこ
       から読まれるのかを制御できません。 YY_INPUT が呼ばれるのは
       スキャナがバッファの終りに到達する時だけですので、例 え ば
       "include" のように入力元を切り替える必要のある文をスキャン
       した後でも長時間を費す場合があります。

       この様な問題を解決するため、 flex は複数の入力バッファを生
       成して切り替える機構を提供します。入力バッファは次のように
       生成されます:

           YY_BUFFER_STATE yy_create_buffer( FILE *file, int size )

       これは FILE ポインタと size を取り、与えられる file に関連
       し size 文字を保持するに十分なバッファを生成します (疑わし
       い場合には size には YY_BUF_SIZE を使用して下さい)。 こ れ
       は、 別のルーチン(下記参照)に渡すための YY_BUFFER_STATE ハ
       ンドルを返します。 YY_BUFFER_STATE  の タ イ プ は  struct
       yy_buffer_state   構造体へのポインタであるため、安全のため
       YY_BUFFER_STATE 変数を ((YY_BUFFER_STATE) 0) と初期化す る
       ことが出来、スキャナではなくソースファイルにおいて入力バッ
       ファを正しく宣言するためにこの構造体を参照することが出来ま
       す。  yy_create_buffer   呼 び出しにおける FILE ポインタは
       YY_INPUT から見える yyin の値と同じようにだけ使用される こ
       と に注意して下さい; YY_INPUT を再定義して yyin を使わない
       ようにすることにより、 yy_create_buffer に対して安全にニル
       FILE  ポインタを渡せます。スキャンするバッファを選択するた
       めには次のようにします:

           void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer )

       これはスキャナの入力バッファを切 り 替 え、 ト ー ク ン が
       new_buffer  から来るようになります。新たなファイルをオープ
       ンして yyin を指すのではなく、スキャンを継続す る た め に
       yywrap() から yy_switch_to_buffer() を使用することがあるこ
       とに注意して下さい。また、 yy_switch_to_buffer()  ま た は
       yywrap() による入力元の切り替えは開始条件を変更し ないこと
       にも注意して下さい。

           void yy_delete_buffer( YY_BUFFER_STATE buffer )

       はバッファに関連づけられたストレージの返還要求に使用 し ま
       す。(  buffer はニルでも構いませんがこの場合このルーチンは
       何もしません。) 現在のバッファの内容をクリアするには次のよ
       うにします:

           void yy_flush_buffer( YY_BUFFER_STATE buffer )

       こ の 関数はバッファの内容を捨てるため、次にスキャナがこの
       バッファとトークンのマッチを行う場合、 ス キャ ナ は ま ず
            */
           %x incl

           %{
           #define MAX_INCLUDE_DEPTH 10
           YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH];
           int include_stack_ptr = 0;
           %}

           %%
           include             BEGIN(incl);

           [a-z]+              ECHO;
           [^a-z\n]*\n?        ECHO;

           <incl>[ \t]*      /* eat the whitespace */
           <incl>[^ \t\n]+   { /* got the include file name */
                   if ( include_stack_ptr >= MAX_INCLUDE_DEPTH )
                       {
                       fprintf( stderr, "Includes nested too deeply" );
                       exit( 1 );
                       }

                   include_stack[include_stack_ptr++] =
                       YY_CURRENT_BUFFER;

                   yyin = fopen( yytext, "r" );

                   if ( ! yyin )
                       error( ... );

                   yy_switch_to_buffer(
                       yy_create_buffer( yyin, YY_BUF_SIZE ) );

                   BEGIN(INITIAL);
                   }

           <<EOF>> {
                   if ( --include_stack_ptr < 0 )
                       {
                       yyterminate();
                       }

                   else
                       {
                       yy_delete_buffer( YY_CURRENT_BUFFER );
                       yy_switch_to_buffer(
                            include_stack[include_stack_ptr] );
                       }
                   }

       ファ イ ルではなくメモリ上の文字列をスキャンするための入力

       ど ちらの関数も文字列もしくはバイト列の コピーを生成してか
       らスキャンします。( yylex() はスキャンするバッファの内容を
       変更するため、これが望ましいのです。) コピーを避けるために
       は次のようにします:

       yy_scan_buffer(char *base, yy_size_t size)
              バッファ内で base から size バイトの長さをスキャ ン
              し ま す。 最 後の 2 バイトは YY_END_OF_BUFFER_CHAR
              (ASCII NUL) である 必要があります。これらの最後の 2
              バ イトはスキャンされません; そのためスキャンの内容
              は base[0] から base[size-2] までで両端を含みます。

              この様になるように base を設定しなかった場合(つまり
              最後の 2 つの YY_END_OF_BUFFER_CHAR バイトを忘れ た
              場合)、 yy_scan_buffer() は新しいバッファを生成する
              のではなくニルポインタを返します。

              型 yy_size_t は整数型であり、バッファの大きさを反映
              する整数式をこの型にキャストすることが出来ます。


ファイルの終りのルール

       特別ルール "<<EOF>>" は、ファイルの終了時もしくは yywrap()
       が非ゼロ(すなわち処理するファイルが無いことを表す)の時に行
       わ れるべきアクションを表します。アクションは以下の 4 つの
       うちのいずれかで終る必要があります。

       -      yyin に新しいファイルを割り当てる(前のバージョン の
              flex では、割り当て後に特別なアクション YY_NEW_FILE
              を呼び出す必要がありました; 今では不要です。);

       -      return 文を実行する;

       -      特別な yyterminate() アクションを実行する;

       -      yy_switch_to_buffer() を使用して新たなバッファに 切
              り替える (上記例で示した通り)。

       <<EOF>> ルールを他のパターンと共に使用してはなりません; 他
       のパターンは開始条件のリストともにだけ満たされるからです。
       満たされない <<EOF>> ルールが与えられた場合、 <<EOF>> アク
       ションをまだ持っていない 全ての開始条件に適用さ れ ま す。
       <<EOF>> ルールを最初の開始条件だけに指定するためには次のよ
       うにして下さい。

           <INITIAL><<EOF>>


       これらのルールは閉じていないコメントを捕まえる場合等に便利
       です。例えば:

           %x quote



雑多なマクロ

       マクロ YY_USER_ACTION にはマッチルールアクションに先だって
       常に行うアクションを定義できます。例えば、yytext を小文 字
       に 変 換 す る ル ー チ ン を呼ぶように #define 出来ます。
       YY_USER_ACTION 起動時には、変数 yy_act はマッチしたルー ル
       の 番 号 を与えます(ルールは 1 番から数えます)。各ルールが
       マッチする頻度を知りたい場合を想像して下さい。以下に仕掛け
       を示します:

           #define YY_USER_ACTION ++ctr[yy_act]

       こ こで ctr は配列であり、それぞれのルールがマッチした回数
       を計数します。マクロ YY_NUM_RULES はルールの総数を表 す た
       め( -s を使った時でさえデフォルトルールを含みます)、正しい
       ctr の宣言は次のようになります:

           int ctr[YY_NUM_RULES];


       マクロ YY_USER_INIT には最初のスキャンの前に常に行う ア ク
       ションを再定義できます (スキャナの内部初期化の前に行われま
       す)。例えばデータ表を読み込んだり、ログファイルをオープ ン
       するために使用できます。

       マクロ yy_set_interactive(is_interactive) は現在のバッファ
       が 対話的と見倣されているか否かを制御するために使 用 し ま
       す。対話的なバッファの処理は遅くなりますが、スキャナの入力
       元が対話的でありバッファをフィルするのを待つことに起因する
       問 題 を 避 けるためには指定しなければなりません(以下の -I
       %option interactive フラグに関する議論を参照して下さ い)。
       マクロ起動時に非ゼロを指定するとバッファは対話的になり、ゼ
       ロを指定すると非対話的になります。このマ ク ロ の 使 用 は
       %option interactive , %option always-interactive , %option
       never-interactive に優先します(下記オプションを参照して 下
       さ い)。バッファをスキャンして対話的である(もしくはでない)
       と判断される前に、 yy_set_interactive() を起動して下さい。

       マクロ yy_set_bol(at_bol) は現在のバッファにおける次のトー
       クンに対するマッチのためのスキャンが行頭から始まるか否かを
       制御します。非ゼロのマクロ引数は、'^' が付いたルールを有効
       にしますが、ゼロのマクロ引数は '^' が付いたルールを無効 に
       します。

       現 在 のバッファからスキャンされた次のトークンが有効な '^'
       ルールを持つ時、マクロ YY_AT_BOL() は真を返します。そう で
       ない場合は偽を返します。

       生 成 さ れ たスキャナでは、全てのアクションは大きな一つの
       switch 文に集められ、 YY_BREAK で分 け ら れ て い ま す。
       YY_BREAK  は再定義可能です。デフォルトではそれぞれのルール
              いけません(終りに文字を追加してはいけない)。

              スキャナの記述の最初の部分に特別な指示である %array
              が書かれているとき、 yytextchar  yytext[YYLMAX]
              と 定義されます。 YYLMAX はマクロで、デフォルトの値
              (多くの場合8KB) を変更したい場合には最初の部分で 再
              定 義可能です。 %array を使うといくらか遅いスキャナ
              になりますが、 yytext の値は input()unput()  の
              呼 び出しでも破壊されなくなります。 yytext が文字ポ
              インタである場合、これらの関数呼び出しは yytext  を
              破 壊 す る 可 能性があります。 %array と対称な指定
              %pointer がデフォルトです。

              C++ のスキャナクラスを生成する (オプション -+ )  と
              きには %array は使えません。

       -      int yyleng 現トークンの長さを保持しています。

       -      FILE *yyin はデフォルトで flex が読むファイルです。
              再定義することは可能ですが、スキャンを始め る 前 か
              EOF   に 到達した後でのみ再定義は意味を持ちます。ス
              キャンの途中で変更すると予想外の結果をもた ら し ま
              す。 というのも flex は入力をバッファリングしている
              からです; そのような場合には、 直 接 再 定 義 せ ず
              yyrestart()   を 使って下さい。ファイルの終わりでス
              キャンが終了した場合には yyin を新しい入力ファイ ル
              に 割り当て、再びスキャナを呼び出してスキャンを続け
              ることが出来ます。

       -      void yyrestart( FILE *new_file ) を呼ぶことで  yyin
              が 新 し い入力ファイルを指すように出来ます。新しい
              ファイルへの変更はすぐに行われます (それまでに バッ
              ファに読み込まれていた入力は失われます)。 yyin を引
              数として yyrestart() を呼ぶと、現在の入力バッファを
              捨 てて同じ入力ファイルをスキャンし続けることに注意
              して下さい。

       -      FILE *yyoutECHO アクションが行われる対象の ファ
              イルです。ユーザが再割当することが出来ます。

       -      YY_CURRENT_BUFFER     カ  レ  ン  ト  バッ  ファ の
              YY_BUFFER_STATE ハンドルを返します。

       -      YY_START 現在の開始条件に対応する整数値を返します。
              続いてこの値を BEGIN と共に使うことで、スキャナをそ
              の開始条件へ戻すことが出来ます。


YACC とのインタフェース

       flex の主な使用方法の一つは、 yacc パーサジェネレータと 共
       に 使用することです。 yacc パーサは yylex() と言う名前のル
       ーチンを呼び、次の入力トークンを見付けるものとしています。
       このルーチンは、次のトークンの型を返し、関連する値をグロー



オプション

       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 の実装に対して最大限の互換性を持たせま
              す。これは 完全な互換性を意味しません。このオプショ
              ン を使用すると性能に大きな影響があります。このオプ

              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 と等価です (以下を参照)。これ
              は -+ オプションとは同時に指定できません。
              時です。高性能追求時にはこれらのオプションを使用 し
              て いるべきですので、これらのオプションを使用してい
              ない場合には、 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 の出力のフラグの要約を調べて
              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 を使用していない場合に
              は、一般にこのオプションは性能をあまり改善 し ま せ
              オプション -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

              来 ます。しかし、このオプションは 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" と等価(デフォルト)
              のオプションは 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 noyy-
       more) ものとします。

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

           %option outfile="ABC"

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

           %option prefix="XYZ"

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

           %option yyclass="foo"

       は C++ スキャナ生成時のみ有効( -+ オプション)です。これ は
           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 ]

       最初の数行は、 '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;

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

       バックアップメッセージはカスケードすることが多いです。複雑
       なルールの組では、数百ものメッセージを得るのは普通のことで
       す。しかし、これを解析すれば、バックアップを除去するために
       は 大 抵の場合数ダースのルールにだけ関係あることが分かるで
           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);

       今度は、改行毎に別のアクションの処理を行うのではなく、改行
       認識はルール間で "分散" され、可能な限り長いテキストにマッ
       チするようになっています。ルールの 追加はスキャナを遅く し
           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 */

       イズを動的に変更すると処理が遅くなります。なぜなら、(巨 大
       な) トークンを再度先頭からスキャンしなおさねばならないから
       です。性能が重要な場合、テキストの "大きな" 部分にマッチさ
       せるべきですが "巨大な" 部分にマッチさせるべきではありませ
       ん。両者の堺目は 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
              現在のデバッグフラグの設定を返します。
              ジェクトを構築します。指定しない場合にはそれぞれ ス
              トリームのデフォルト 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 に書き、終了
              します。


           %{
           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)

           #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 に合致しています。
              こ の呼び出しにより入力バッファは捨てられることに注
              意して下さい; 通常これは対話的スキャナでは問題で は
              ありません。

              ま た、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 はこの機能をサポートしません。

              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();

       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 scan-
       ner uses REJECT - スキャナは非常に大きなトークンのマッチを
       調べていて、入力バッファを拡張する必要が起きました。しかし
       ながら、バッファの拡張は REJECT を使うスキャナでは働きませ
       ん。

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

              う名前になります)。

       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
       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  Genera-
       tor

       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 For-
       rest, 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 Rom-
       mel, Jim Roskind, Alberto Santini, Andreas  Scherer,  Dar-
       rell Schiebel, Raf Schietekat, Doug Schmidt, Philippe Sch-
       noebelen, Andreas Schwab, Larry  Schwimmer,  Alex  Siegel,
       Eckehard Stolz, Jan-Erik Strvmquist, Mike Stump, Paul Stu-
       して; Kent Williams と Tom Epperly には C++ クラスサポート
       に 関 し て; Ove Ewerlid には NUL のサポートに関して; Eric
       Hughes には複数バッファのサポートに関して、それぞれ感謝 し
       ます。

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

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



Version 2.5                 April 1995                    FLEX(1)

ABELNET VPSサービス