Flex は、入力テキストを C または C++ のアクションに対応付ける規則からスキャナーを生成します。スキャナーは通常、パーサーにトークンを供給しますが、テキストの変換や、正則言語形式の検証にも使用できます。Flex マニュアル では、生成されるインターフェイスとオプションごとの動作が定義されています。
仕様の構造 #
.l ファイルには、%% で区切られた 3 つのセクションがあります。定義、規則、ユーザーコードです。定義には、C の宣言、名前付き正規表現、開始条件を記述します。規則では、パターンとアクションを対応付けます。最後のセクションには、補助関数と、必要に応じてドライバーを記述します。
%option noyywrap
%{
#include "parser.h"
%}
identifier [[:alpha:]_][[:alnum:]_]*
%%
[[:space:]]+ ;
{identifier} return IDENTIFIER;
"+" return '+';
. return INVALID;
%%Flex は、入力テキストのうち 最長 の部分に一致する規則を選択します。同じ長さの複数の規則が一致する場合は、先に記述された規則を選択します。デフォルト規則は、一致しなかった文字を標準出力にコピーします。一致しなかった入力を報告する必要がある場合は、明示的なキャッチオール、または -s/%option nodefault を使用してください。
正規表現とスキャナーの状態 #
Flex のパターンは正則言語を記述します。名前付き定義によって重複を減らし、文字クラスによってロケール対応のグループを表現し、引用符で囲んだテキストによってリテラル文字列に一致させます。言語トークンでメタ文字をそのまま使用する必要がある場合は、エスケープするか引用符で囲んでください。
開始条件によって規則セットを分割できます。包含的な条件は %s、排他的な条件は %x で宣言し、<STATE> を付けて規則を修飾します。
%x COMMENT
%%
"/*" BEGIN(COMMENT);
<COMMENT>"*/" BEGIN(INITIAL);
<COMMENT>\n ++line;
<COMMENT>. ;
<COMMENT><<EOF>> return UNTERMINATED_COMMENT;包含的な条件では修飾されていない規則も有効ですが、排他的な条件では、その条件またはすべての状態に対して明示的に修飾された規則だけが実行されます。Flex が生成するデフォルト規則は、%option nodefault または明示的なキャッチオールで置き換えない限り、すべての状態で有効です。状態を変更するには BEGIN を使用し、アクションで現在の状態を調べる必要がある場合は YY_START を使用します。途中で入力が終了する可能性のある状態では <<EOF>> を処理してください。文字列、コメント、インデント、または字句モードは、1 つのパターンで文脈依存の構造を表そうとせず、明示的な状態としてモデル化します。
生成される API、バッファー、再入可能性 #
デフォルトでは、Flex は yylex() と、yytext、yyleng、入力バッファーの状態などのグローバル変数を生成します。%option prefix="project_" は生成される公開シンボルの名前を変更し、1 つのプログラム内で複数のスキャナーを使用できるようにします。%option outfile="scanner.c" は生成先ファイルを選択します。同じ設定はコマンドラインオプションでも指定できます。
スキャナーはバッファーを介して入力を読み取ります。yyrestart(FILE*) は入力を再開し、yy_scan_string または yy_scan_bytes は呼び出し元が提供したメモリをスキャンします。yy_scan_* 関数で作成したバッファーは yy_delete_buffer で削除してください。ネストした入力が必要な場合は、管理対象バッファー間を yy_switch_to_buffer で切り替えます。
%option reentrant はスキャナーハンドル (yyscan_t) を作成し、生成される API がそのハンドルを受け取るように変更します。yylex_init/yylex_destroy(または _extra 版)でハンドルを初期化および破棄し、グローバル変数ではなく yyextra を通じてスキャナーごとの状態を渡します。パーサーまたはスレッドを独立して動作させる必要がある場合は、このモードを使用してください。
パーサーとの統合と診断 #
Bison と統合する場合は、対応するトークン宣言を設定し、生成されたパーサーヘッダーをインクルードします。%option bison-bridge はスキャナーインターフェイスを介して意味値を渡し、%option bison-locations はさらに位置情報を渡します。空白やコメントを含め、消費したすべての文字について位置情報を更新しないと、診断がソース位置からずれてしまいます。
トークン化エラーとパーサーの構文エラーは区別してください。スキャナーはソース範囲を伴う無効なトークンを返すか報告します。パーサーは文法上のコンテキストで予期しないトークンを説明し、意図的に定めた同期ポイントでのみ回復します。
コメント
GitHub で閲覧・コメントする(投稿にはログインが必要です)