Manpages

名 称

flex − 高 速 な 字 句 解 析 処 理 系 の 生 成 ツ ー ル

書 式

flex [−bcdfhilnpstvwBFILTV78+? −C[aefFmr] −ooutput −Pprefix −Sskeleton] [−−help −−version] [filename ...]

概 説

本 マ ニ ュ ア ル は 、 テ キ ス ト の パ タ ー ン マ ッ チ ン グ を 行 う プ ロ グ ラ ム を 生 成 す る ツ ー ル flex を 扱 い ま す 。 本 マ ニ ュ ア ル は チ ュ ー ト リ ア ル と リ フ ァ レ ン ス 節 と を 含 み ま す : 解 説 ツ ー ル の 短 い 概 説 簡 単 な 例 入 力 フ ァ イ ル の フ ォ ー マ ッ ト パ タ ー ン

flex が 使 用 す る 拡 張 し た 正 規 表 現 入 力 の マ ッ チ 方 法 何 が マ ッ チ す る か を 決 定 す る 規 則 ア ク シ ョ ン パ タ ー ン が マ ッ チ し た 時 に 何 を 行 う か を 指 定 す る 方 法 生 成 さ れ た ス キ ャ ナ
flex が 生 成 す る ス キ ャ ナ に 関 す る 詳 細 ; 入 力 元 の 制 御 方 法 開 始 条 件 ス キ ャ ナ へ の 文 脈 の 導 入 と 、
"ミ ニ ス キ ャ ナ " の 制 御 方 法 複 数 の 入 力 バ ッ フ ァ 複 数 の 入 力 元 を 扱 う 方 法 ; フ ァ イ ル で は な く 文 字 列 か ら ス キ ャ ン す る 方 法 フ ァ イ ル の 終 り の ル ー ル フ ァ イ ル の 終 り に マ ッ チ す る 特 別 な ル ー ル 雑 多 な マ ク ロ ア ク シ ョ ン で 使 用 可 能 な マ ク ロ の ま と め ユ ー ザ が 使 用 可 能 な 値 ア ク シ ョ ン で 使 用 可 能 な 値 の ま と め

Yacc と の イ ン タ フ ェ ー ス
lex ス キ ャ ナ と yacc パ ー サ と の 結 合 オ プ シ ョ ン
flex の コ マ ン ド ラ イ ン オ プ シ ョ ン と 、
"%option" デ ィ レ ク テ ィ ブ 性 能 関 連 ス キ ャ ナ を 可 能 な 限 り 高 速 に す る 方 法

C++ ス キ ャ ナ の 生 成
C++ ス キ ャ ナ ク ラ ス 生 成 の た め の
(実 験 的 な ) 機 能

Lex お よ び POSIX と の 非 互 換 性
AT&T lex お よ び POSIX lex 標 準 と
flex と の 違 い 診 断
flex (も し く は 生 成 し た ス キ ャ ナ ) が 出 力 す る エ ラ ー メ ッ セ ー ジ で 意 味 が 明 確 で な い も の 関 連 フ ァ イ ル
flex が 使 用 す る フ ァ イ ル 欠 陥
/ バ グ
flex の 既 知 の 問 題 関 連 項 目 ツ ー ル に 関 係 す る 他 の ド キ ュ メ ン ト 作 者 連 絡 方 法 を 含 み ま す

解 説

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

簡 単 な 例

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

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

%{
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 の よ う な 言 語 の 単 純 な ス キ ャ ナ の 原 型 で す 。 異 な っ た タ イ プ の ト ー ク ン を 定 義 し 、 こ れ を 見 付 け る と 報 告 し ま す 。 こ の 例 の 詳 細 は 、 以 降 の 節 で 説 明 し ま す 。

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

flex の 入 力 フ ァ イ ル は 3 つ の 部 分 か ら な り 、 %% だ け か ら な る 行 に よ り 分 け ら れ ま す : 定 義
%% ル ー ル
%% ユ ー ザ コ ー ド 定 義 部 分 は 、 ス キ ャ ナ の 宣 言 を 単 純 化 す る 単 純 な 名 前 の 定 義 の 宣 言 と 、 後 で 説 明 す る 開 始 条 件 の 宣 言 と か ら な り ま す 。 名 前 の 定 義 は 次 の 形 式 で す : 名 前  定 義

"名 前 " は 語 で あ り 、 レ タ ー か ア ン ダ ー ス コ ア (’_’) か ら 始 ま っ て 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 番 目 の %% も 省 略 で き ま す 。 定 義 と ル ー ル の 部 分 で は 、 イ ン デ ン ト さ れ た テ キ ス ト と %{%} と の 間 の テ キ ス ト は そ の ま ま の 形 で 出 力 に コ ピ ー さ れ ま す (こ の 際 %{} は 削 除 さ れ ま す )。 %{} は イ ン デ ン ト さ れ て い な い 行 に 現 れ る 必 要 が あ り ま す 。 ル ー ル の 部 分 で は 、 最 初 の ル ー ル の 前 に 現 れ る イ ン デ ン ト さ れ た も し く は %{} 部 分 の テ キ ス ト は 、 ス キ ャ ン ル ー チ ン に ロ ー カ ル な 変 数 と 、 (宣 言 の 後 で は )ス キ ャ ン ル ー チ ン に 入 る た び に 実 行 さ れ る コ ー ド と を 宣 言 し ま す 。 ル ー ル 部 分 の 他 の イ ン デ ン ト さ れ た も し く は %{} 部 分 の テ キ ス ト は 出 力 に コ ピ ー さ れ ま す が 、 意 味 は ち ゃ ん と 定 義 さ れ て お ら ず コ ン パ イ ル 時 に エ ラ ー と な る か も 知 れ ま せ ん (こ の 仕 様 は POSIX 互 換 の た め に あ り ま す ; 他 の こ の よ う な 仕 様 は 以 降 を 見 て 下 さ い )。 定 義 の 部 分 (ル ー ル の 部 分 で は な い で す )で は 、 イ ン デ ン ト さ れ て い な い コ メ ン ト ("/*" か ら 始 ま る 行 ) は 次 の "*/" ま で そ の ま ま の 形 で コ ピ ー さ れ ま す 。

パ タ ー ン

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

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 の 組 合 せ は 複 数 あ り ま す ;
"危 険 な 右 文 脈 " に つ い て は 、 以 降 の 、 欠 陥
/ バ グ の 節 の 記 述 を 見 て 下 さ い 。 )
^r 行 頭 に あ る r。 (ス キ ャ ン の 始 ま り も し く は ス キ ャ ン さ れ た 改 行 の 右 で す
)。
r$ 行 末 に あ る r。 "r/\n" と 等 価 (改 行 の 前 で す )。
"r/\n" と 同 じ で す 。

flex の "改 行 " の 表 現 は flex を コ ン パ イ ル し た
C コ ン パ イ ラ が 解 釈 す る ’\n’ と 完 全 に 一 致 す る こ と に 注 意 し て 下 さ い ; 特 定 の シ ス テ ム
DOS で は \r を 入 力 か ら 取 り 除 く か
"r$" を 表 す た め に 明 示 的 に r/\r\n を 使 用 す る 必 要 が あ り ま す 。

<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 関 数 に 適 合 す る 全 て の 文 字 集 合 を 指 示 し ま す 。 例 え ば 、 [:alnum:]isalnum() が 真 を 返 す 文 字 を 指 示 し ま す - す な わ ち す べ て の ア ル フ ァ ベ ッ ト と 数 字 で す 。 isblank(), が 無 い シ ス テ ム で は 、 flex は [:blank:] を 空 白 と タ ブ と 定 義 し ま す 。 例 え ば 以 下 の 表 現 は 全 て 同 じ で す :

[[:alnum:]]
[[:alpha:][:digit:]]
[[:alpha:]0-9]
[a-zA-Z0-9] ス キ ャ ナ が 大 文 字 小 文 字 を 意 識 し な い 場 合 ( −i フ ラ グ 指 定 時 ) [:upper:][:lower:][:alpha:] と 同 じ で す 。 パ タ ー ン に 関 す る 注 意 点 で す :

- 否 定 文 字 ク ラ ス 、 例 え ば 上 の

"[^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 に よ り 使 用 可 能 と な り 、 長 さ が グ ロ ー バ ル 整 数 yyleng に よ り 使 用 可 能 と な り ま す 。 そ の 後 、 マ ッ チ し た パ タ ー ン に 対 応 す る ア ク シ ョ ン が 実 行 さ れ (ア ク シ ョ ン の 詳 細 な 記 述 は 後 で 行 い ま す )、 残 り の 入 力 が 残 り の マ ッ チ の た め に ス キ ャ ン さ れ ま す 。 マ ッ チ が 見 付 か ら な い と 、 デ フ ォ ル ト ル ー ル が 実 行 さ れ ま す : 入 力 の 次 の 文 字 が マ ッ チ し た と 見 倣 さ れ 、 標 準 出 力 に コ ピ ー さ れ ま す 。 最 も 簡 単 で 正 当 な flex の 入 力 は 以 下 の 通 り で す :

%% こ れ は 、 入 力 を 単 純 に 出 力 に コ ピ ー (1 度 に 1 文 字 ず つ )す る ス キ ャ ナ を 生 成 し ま す 。

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"

(入 力 の 他 の 全 て の 文 字 を 出 力 に コ ピ ー し ま す 。 な ぜ な ら デ フ ォ ル ト ル ー ル に マ ッ チ す る か ら で す 。 ) 次 は 、 複 数 の 空 白 や 文 字 を 単 一 の 空 白 に 圧 縮 し 行 末 の 空 白 を 捨 て る プ ロ グ ラ ム で す :

%%
[ \t]+ putchar( ’ ’ );
[ \t]+$ /* ignore this token */ ア ク シ ョ ン が ’{’ を 含 む 場 合 、 ア ク シ ョ ン は 対 応 す る ’}’ ま で 続 き 、 複 数 行 に 渡 る 場 合 も あ り ま す 。 flex は C の 文 字 列 お よ び コ メ ン ト に 関 し て 知 っ て お り 、 そ れ ら の 中 の ブ レ ー ス を 誤 解 す る こ と は あ り ま せ ん が 、 ア ク シ ョ ン が %{ で 始 ま る こ と を 許 し 、 次 の %} ま で の テ キ ス ト が ア ク シ ョ ン で あ る と し ま す (ア ク シ ョ ン 内 部 の 任 意 個 の ブ レ ー ス に は 関 係 あ り ま せ ん )。 垂 直 バ ー (’|’) の み か ら な る ア ク シ ョ ン は "次 の ル ー ル と 同 じ " を 意 味 し ま す 。 説 明 は 以 下 を 見 て 下 さ い 。 ア ク シ ョ ン は 任 意 の C コ ー ド を 含 む こ と が 出 来 ま す 。 こ れ に は 、 yylex() を 呼 び 出 し た ル ー チ ン に 対 し て 値 を 返 す return 文 も 含 ま れ ま す 。 yylex() が 呼 ば れ る た び 、 最 後 に 残 っ た ト ー ク ン か ら 処 理 を 再 開 し 、 フ ァ イ ル の 終 了 も し く は return を 実 行 す る ま で 処 理 を 行 い ま す 。 ア ク シ ョ ン は 自 由 に yytext を 変 更 で き ま す が 、 例 外 は 長 さ を 増 や す こ と で す (文 字 を 末 尾 に 加 え る こ と に な り 、 こ れ は 入 力 ス ト リ ー ム の 後 続 す る 文 字 を 上 書 き し ま す )。 こ れ は %array 使 用 時 に は 当 て は ま り ま せ ん (上 述 ); こ の 場 合 yytext を 自 由 に 変 更 で き ま す 。 ア ク シ ョ ン は 自 由 に yyleng を 変 更 で き ま す が 、 ア ク シ ョ ン が yymore() を 使 用 す る 時 に は 例 外 的 に 変 更 し て は い け ま せ ん (後 述 )。 多 く の 特 別 な デ ィ レ ク テ ィ ブ が あ り 、 ア ク シ ョ ン 中 に 含 め る こ と が 出 来 ま す :

-

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

-

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

-

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

int word_count = 0;
%%

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

REJECT が 無 い 場 合 、 入 力 中 の "frob" は 語 と し て 数 え ら れ ず 、 ス キ ャ ナ は 通 常 通 り ト ー ク ン 毎 に 1 つ の ア ク シ ョ ン だ け を 行 い ま す 。 複 数 の REJECT を 使 用 可 能 で あ り 、 そ れ ぞ れ 現 在 有 効 な ル ー ル の 次 に 良 い 選 択 を 見 付 け ま す 。 例 え ば 次 の ス キ ャ ナ は 、 "abcd" と い う ト ー ク ン を ス キ ャ ン し 、 出 力 に "abcdabcaba" を 書 き ま す :

%%
a |
ab |
abc |
abcd ECHO; REJECT;
.|\n /* eat up any unmatched character */

(前 の 3 つ の ル ー ル は 4 番 目 の ル ー ル の ア ク シ ョ ン を 共 有 し ま す 。 な ぜ な ら 特 別 な ’|’ ア ク シ ョ ン が 使 用 さ れ て い る か ら で す 。 ) 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 を 入 力 ス ト リ ー ム へ 戻 し ま す 。 戻 し た 文 字 は 次 に ス キ ャ ン さ れ る 文 字 に な り ま す 。 次 の ア ク シ ョ ン は 現 在 の ト ー ク ン を 取 り 上 げ 、 括 弧 内 に 入 れ て 再 ス キ ャ ン し ま す 。

{
int i;
/* Copy yytext because unput() trashes yytext */
char *yycopy = strdup( yytext );
unput( ’)’ );
for ( i = yyleng - 1; i >= 0; --i )
unput( yycopy[i] );
unput( ’(’ );
free( yycopy ); }

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 に て リ フ ィ ル し ま す (生 成 さ れ た ス キ ャ ナ で 後 述 )。 こ の ア ク シ ョ ン は 、 複 数 の 入 力 バ ッ フ ァ に お い て 後 述 す る よ り 一 般 的 な yy_flush_buffer() 関 数 の 特 別 な ケ ー ス で す 。

-

yyterminate() ア ク シ ョ ン の return 文 の 代 わ り に 使 う こ と が 出 来 ま す 。 yyterminate() は ス キ ャ ナ を 終 了 し 、 "全 て 終 了 " を 意 味 す る 0 を 呼 び 出 し 元 関 数 に 返 し ま す 。 デ フ ォ ル ト で は yyterminate() は フ ァ イ ル の 終 わ り に 達 し た と き に も 呼 ば れ ま す 。 yyterminate() は マ ク ロ で あ り 、 定 義 し な お す こ と が で き ま す 。

生 成 さ れ た ス キ ャ ナ

flex の 出 力 は lex.yy.c と い う フ ァ イ ル で あ り 、 ス キ ャ ン ル ー チ ン yylex() と 、 ト ー ク ン の マ ッ チ ン グ に 使 用 す る 複 数 の テ ー ブ ル と 、 複 数 の 付 属 ル ー チ ン と マ ク ロ か ら な り ま す 。 デ フ ォ ル ト で は 、 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 文 字 を 用 意 し 、 整 数 変 数 result 中 に 読 め た 文 字 数 も し く は 定 数 YY_NULL (Unix シ ス テ ム で は 0)を 入 れ て 返 し ま す 。 デ フ ォ ル ト の YY_INPUT は グ ロ ー バ ル フ ァ イ ル ポ イ ン タ "yyin" か ら 読 み ま す 。

YY_INPUT の サ ン プ ル 定 義 で す (入 力 フ ァ イ ル の 定 義 部 に 格 納 ):

%{
#define YY_INPUT(buf,result,max_size) \
{ \
int c = getchar(); \
result = (c == EOF) ? YY_NULL : (buf[0] = c, 1); \ }
%} こ の 定 義 に よ り 、 入 力 処 理 は 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 ア ク シ ョ ン が 実 行 さ れ る ま で 、 与 え ら れ た 開 始 条 件 の ル ー ル は 有 効 で あ り 、 他 の 開 始 条 件 の ル ー ル は 無 効 で す 。 開 始 条 件 が 内 包 的 な 場 合 、 開 始 条 件 を 持 た な い ル ー ル も ま た 有 効 で す 。 開 始 条 件 が 排 他 的 な 場 合 、 開 始 条 件 を 満 た す ル ー ル だ け が 有 効 で す 。 同 じ 排 他 開 始 条 件 に 依 存 す る ル ー ル の 組 は 、 flex 入 力 中 の 別 の ル ー ル と は 独 立 な ス キ ャ ナ を 記 述 し ま す 。 そ の た め 、 排 他 開 始 条 件 を 使 用 す れ ば 、 "ミ ニ ス キ ャ ナ " (別 部 分 と は 文 法 的 に 異 な る 部 分 (例 え ば コ メ ン ト )に 対 す る ス キ ャ ナ ) を 簡 単 に 指 定 で き ま す 。 内 包 的 開 始 条 件 と 排 他 的 開 始 条 件 と が ま だ 少 し 曖 昧 で あ る な ら 、 両 者 の 関 係 を 表 す 例 を 示 し て 説 明 し ま す 。 以 下 の ル ー ル の 組 :

%s example
%%

<example>foo do_something();

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

<SPECIAL>blahblahblah
...more rules follow... 開 始 条 件 を 説 明 す る た め に 、 "123.456" の よ う な 文 字 列 を 2 通 り の 異 な っ た 解 釈 を す る ス キ ャ ナ を 示 し ま す 。 デ フ ォ ル ト で は こ れ は 、 整 数 "123" と ド ッ ト (’.’) と 整 数 "456" の 3 ト ー ク ン に 数 え ら れ ま す 。 し か し 、 こ の 文 字 列 の 前 に "expect-floats" の 文 字 列 が あ る 場 合 、 こ れ は 単 一 の ト ー ク ン で あ る と さ れ 、 浮 動 小 数 点 数 123.456 と さ れ ま す :

%{
#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
%%
int line_num = 1;
int comment_caller;

"/*" {
comment_caller = INITIAL;
BEGIN(comment); }

...

<foo>"/*" {
comment_caller = foo;
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(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 */

*string_buf_ptr++ = result; }

<str>\\[0-9]+ {
/* generate error - bad escape sequence; something
* like ’\48’ or ’\0777777’
*/ }

<str>\\n *string_buf_ptr++ = ’\n’;
<str>\\t *string_buf_ptr++ = ’\t’;
<str>\\r *string_buf_ptr++ = ’\r’;
<str>\\b *string_buf_ptr++ = ’\b’;
<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 を 使 用 し て そ の 開 始 条 件 に 切 り 替 え ま す 。
int yy_top_state()
ス タ ッ ク の 内 容 を 変 更 せ ず に 、 ス タ ッ ク の 先 頭 を 返 し ま す 。 開 始 条 件 ス タ ッ ク は 動 的 に 大 き く な り 、 ま た 組 み 込 み 時 の サ イ ズ 制 限 は あ り ま せ ん 。 メ モ リ を 使 い 切 る と 、 プ ロ グ ラ ム 実 行 は 中 止 さ れ ま す 。 開 始 条 件 ス タ ッ ク を 使 用 す る た め に は 、 ス キ ャ ナ は %option stack デ ィ レ ク テ ィ ブ を イ ン ク ル ー ド す る 必 要 が あ り ま す (下 記 オ プ シ ョ ン を 参 照 し て 下 さ い )。

複 数 の 入 力 バ ッ フ ァ

ス キ ャ ナ に よ っ て は (フ ァ イ ル の "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 ) こ の 関 数 は バ ッ フ ァ の 内 容 を 捨 て る た め 、 次 に ス キ ャ ナ が こ の バ ッ フ ァ と ト ー ク ン の マ ッ チ を 行 う 場 合 、 ス キ ャ ナ は ま ず YY_INPUT を 使 用 し て こ の バ ッ フ ァ を フ ィ ル し ま す 。

yy_new_buffer()yy_create_buffer() の エ イ リ ア ス で あ り 、 動 的 オ ブ ジ ェ ク ト の 生 成 と 破 壊 の た め に 使 用 す る C++ の newdelete と の 互 換 性 の た め に 提 供 し て い ま す 。 最 後 に YY_CURRENT_BUFFER マ ク ロ は 、 現 在 の バ ッ フ ァ に 対 す る YY_BUFFER_STATE ハ ン ド ル を 返 し ま す 。 こ の 機 能 を 使 用 し て イ ン ク ル ー ド フ ァ イ ル を 展 開 す る ス キ ャ ナ の 記 述 例 で す ( <<EOF>> 機 能 は 後 述 し ま す ):

/* the "incl" state is used for picking up the name
* of an include file
*/
%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] ); } } フ ァ イ ル で は な く メ モ リ 上 の 文 字 列 を ス キ ャ ン す る た め の 入 力 バ ッ フ ァ を 設 定 す る た め の 3 つ の ル ー チ ン を 使 用 可 能 で す 。 い ず れ も 文 字 列 を ス キ ャ ン す る 新 し い 入 力 バ ッ フ ァ を 生 成 し 、 対 応 す る YY_BUFFER_STATE ハ ン ド ル (終 了 時 に は yy_delete_buffer() に て 消 去 し ま す )を 返 し ま す 。 新 し い バ ッ フ ァ に 切 り 替 え る 時 に は yy_switch_to_buffer() を 使 用 し 、 次 の yylex() の 呼 び 出 し 時 に は こ の 文 字 列 を ス キ ャ ン 開 始 し ま す 。
yy_scan_string(const char *str)

NUL タ ー ミ ネ ー ト さ れ た 文 字 列 を ス キ ャ ン し ま す 。

yy_scan_bytes(const char *bytes, int len)

len バ イ ト (NUL が 含 ま れ る か も 知 れ ま せ ん )を 位 置 bytes か ら ス キ ャ ン し ま す 。 ど ち ら の 関 数 も 文 字 列 も し く は バ イ ト 列 の コ ピ ー を 生 成 し て か ら ス キ ャ ン し ま す 。 ( 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
%%

...other rules for dealing with quotes...

<quote><<EOF>> {
error( "unterminated quote" );
yyterminate(); }
<<EOF>> {
if ( *++filelist )
yyin = fopen( *filelist, "r" );
else
yyterminate(); }

雑 多 な マ ク ロ

マ ク ロ 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 は 再 定 義 可 能 で す 。 デ フ ォ ル ト で は そ れ ぞ れ の ル ー ル の ア ク シ ョ ン を 分 け る た め の 単 な る "break" で す 。 YY_BREAK を 再 定 義 す る こ と に よ り 、 例 え ば C++ ユ ー ザ が #define YY_BREAK を 何 も し な い よ う に 定 義 し (た だ し 全 て の ル ー ル が "break" か "return" で 終 る よ う に 注 意 し な け れ ば な り ま せ ん !)、 ル ー ル の ア ク シ ョ ン が "return" で 終 る こ と に よ り YY_BREAK が ア ク セ ス で き な い こ と に 起 因 す る 、 到 達 で き な い 文 が あ る と い う 警 告 を 避 け る こ と が 出 来 ま す 。

ユ ー ザ が 使 用 可 能 な 値

こ の 節 で は ユ ー ザ が ル ー ル の ア ク シ ョ ン 部 分 で 使 用 可 能 な 値 を ま と め ま す 。

-

char *yytext 現 ト ー ク ン の テ キ ス ト を 保 持 し て い ま す 。 内 容 を 変 更 し て も 構 い ま せ ん が 、 そ の 長 さ を 伸 ば し て は い け ま せ ん (終 り に 文 字 を 追 加 し て は い け な い )。 ス キ ャ ナ の 記 述 の 最 初 の 部 分 に 特 別 な 指 示 で あ る %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() と 言 う 名 前 の ル ー チ ン を 呼 び 、 次 の 入 力 ト ー ク ン を 見 付 け る も の と し て い ま す 。 こ の ル ー チ ン は 、 次 の ト ー ク ン の 型 を 返 し 、 関 連 す る 値 を グ ロ ー バ ル の 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 [AT] 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 [AT] ken.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 [AT] ee.gov に 送 っ て 下 さ い 。