次: Start State Example, 前: Start State Notes, 上: Start States
Flex 2.5では、 以下の新機能を利用することができます。
スタート状態`<*>'には特殊な意味があり、 すべてのスタート状態にマッチします。
例えば、
%x state1
%%
<state1>"one" printf("two");
<*>"three" printf("four");
は、
%s state1
%%
<state1>"one" printf("two");
"three" printf("four");
と同じ意味になります。
マクロYY_STARTにより、
カレントなスタート状態を参照することができます。
前節(Start State Notes)の「スタート状態の名前」に示した例では、
カレントなスタート状態を配列last_stateに格納する処理を、
以下のように記述していますが、
FOO {
last_state[state_count] = FOO;
...
}
この代入は、
last_state[state_count] = YY_START;
のように書き換えることができます。
Lexとの互換性のために、
YYSTATEが、
YY_STARTの別名として定義されています。
スタート状態のスコープを定義することができます。 これにより、 同じスタート状態において複数のルールが存在する時に、 その個々のルールにスタート状態を指定する必要がなくなります。
スタート状態のスコープの形式は、 以下のとおりです。
<start_states>{
...
}
ここで、 start_statesは、 単一のスタート状態、 または、 カンマで区切られたスタート状態のリストです。 スタート状態のスコープの境界は、 `{'と`}'によって指定されます。 スタート状態のスコープを入れ子にすることも可能です。
Activating Statesに示した例を、 スタート状態のスコープを使って書き直すと、 以下のようになります。
%x COMMENT
%%
"{" BEGIN(COMMENT);
<COMMENT>{
"$R"
"$I"
"$M"
...
"}" BEGIN(INITIAL);
}
スキャナ定義ファイルで`%option stack'を指定すると、 スタート状態スタックを利用できます。 スタート状態スタックを操作するために、 以下の関数が提供されています。
void yy_push_state(int new_state)void yy_pop_state()int yy_top_state()前節(Start State Notes)の「スタート状態の名前」に示した例を、 スタート状態スタックを使って書き直すと以下のようになります。
%option stack
%x FOO BAR baz
%%
FOO {
yy_push_state(baz);
}
BAR {
yy_push_state(baz);
}
<baz>rule 1
...
<baz>rule n
<baz>END {
yy_pop_state();
}