Next: Start State Example, Previous: Start State Notes, Up: 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(); }