FLEX(1)

名称
flex - 高速なレキシカルアナライザを作成する

書式
flex [-bcdfhilnpstvwBFILTV78+? -C[aefFmr] -ooutput -Pprefix -Sskeleton] [--help --version] [filename ...]

概要
このマニュアルは、 テキストのパターンマッチングを行うプログラムを作成するツールである flex について記述してあります。 このマニュアルには tutorial と reference の両方のセクションがあります。 以下に、セクションの一覧を示します:
    解説
        このツールの簡単な概要
    いくつかの簡単な例
    入力ファイルのフォーマット
    パターン
        flex で使われている拡張正規表現
    入力がどのようにマッチするか
        何がマッチするかを決定するルール
    アクション
        パターンがマッチした時の動作の記述方法
    作成されるスキャナ
        flex が生成するスキャナの細部を眺める
	入力ソースの制御方法
    初期状態
        スキャナに context を埋め込み、
        "ミニ スキャナ" を管理する
    複数の入力バッファ
        複数の入力ソースの操作方法
	ファイルの代わりに文字列からスキャンする方法
    End-of-file ルール
        入力の終端にマッチさせるための特殊ルール
    雑マクロ
        アクションで利用できるマクロの概要
    ユーザが利用できる値
        アクションで得られる値の概要
    Yacc とのインタフェース
        flex のスキャナと yacc のパーサの接続
    オプション
        flex のコマンドラインオプション
        および "%option" 命令
    パフォーマンスに関する考察
        可能な限り高速なスキャナを作成する方法
    C++ 用スキャナの作成
        C++ スキャナクラスを作成するための (実験的な) 機能
    Lex や POSIX との非互換な面
        flex が AT&T の lex や POSIX の lex とどのように違うか
    診断
        flex (もしくは flex が生成するスキャナ)が表示する、
	意味のはっきりしないエラーメッセージ
    関連ファイル
        flex が利用するファイル
    欠陥 / バグ
        flex の、既にわかっている問題
    関連項目
        他のドキュメント、関連するツール
    作者
        連絡方法を含む
以下にないセクションについては、オリジナルのオンラインマニュアルを参照して 下さい。

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

いくつかの簡単な例

最初に、 flex をどのように使うかという雰囲気をわかってもらうための簡単な例を示します。 以下の flex の入力は、 文字列 "username" を見つけるたびに、それをユーザのログイン名で置き換える スキャナを記述してあります:
    %%
    username    printf( "%s", getlogin() );
デフォルトでは、 flex スキャナにマッチしない全てのテキストは、出力にコピーされます。 よって、このスキャナの正確な機能は、 各 "username" を展開しながら入力を出力にコピーする というものです。 この flex への入力では、ルールがたった 1 つしかありません。 "username" が pattern であり、"printf" が action です。 "%%" はルールの記述の開始を示すマークです。

別の簡単な例を示します:
            int num_lines = 0, num_chars = 0;
    %%
    \n      ++num_lines; ++num_chars;
    .       ++num_chars;
    %%
    main()
            {
            yylex();
            printf( "# of lines = %d, # of chars = %d\n",
                    num_lines, num_chars );
            }
このスキャナは、入力の文字数と行数を数えます (最後に出力されるカウント数以外は 何も出力されません)。 最初の行は、2 つのグローバル変数 "num_lines" および "num_chars" を宣言 しています。これらは、2 番めの "%%" 以降で宣言された yylex() および、 main() ルーチン内でアクセス可能です。 この例には 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" );
        else
                yyin = stdin;

        yylex();
        }
これは、Pascal に似た言語用の簡単なスキャナです。 これは、いろいろなタイプの token を識別し、何を見つけたかをレポートします。

関連ファイル

-lfl
    スキャナがリンクしなければならないファイル。

lex.yy.c
    作成されるスキャナ (システムによっては lexyy.c と呼ばれる)。

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

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

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

lex.backup
    -b フラグ用のバックアップ情報 (システムによっては lex.bck と呼ばれる)。

関連項目

lex(1), yacc(1), sed(1), awk(1).

John Levine, Tony Mason, and Doug Brown, Lex & Yacc, O'Reilly and Associates. Be sure to get the 2nd edition.

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). Describes the pattern-matching techniques used by flex (deterministic finite automata).

作者
Vern Paxson, with the help of many ideas and much inspiration from Van Jacobson. Original version by Jef Poskanzer. The fast table representation is a partial implementation of a design done by Van Jacobson. The implementation was done by Kevin Gong and Vern Paxson.

Thanks to the many flex beta-testers, feedbackers, and contributors, especially 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, and those whose names have slipped my marginal mail-archiving skills but whose contributions are appreciated all the same.

Thanks to Keith Bostic, Jon Forrest, Noah Friedman, John Gilmore, Craig Leres, John Levine, Bob Mulcahy, G.T. Nicol, Francois Pinard, Rich Salz, and Richard Stallman for help with various distribution headaches.

Thanks to Esmond Pitt and Earle Horton for 8-bit character support; to Benson Margulies and Fred Burke for C++ support; to Kent Williams and Tom Epperly for C++ class support; to Ove Ewerlid for support of NUL's; and to Eric Hughes for support of multiple buffers.

This work was primarily done when I was with the Real Time Systems Group at the Lawrence Berkeley Laboratory in Berkeley, CA. Many thanks to all there for the support I received.

Send comments to vern@ee.lbl.gov.