単純なマーク付けがなされた文字列の解析 #16

二つの開始状態INITIALSUCCESSIONの同一パターンに対するアクションにはあまり差がない。
特にエラー処理に関しては空入力に関する一つを除き両者で共通である。
そこで、もう少しまとまらないか考えてみる。

...snip
%%

[^()]+      { printf("string [%s]\n", yytext); if (YY_START == INITIAL) BEGIN(SUCCESSION); }
\([^()]+\)  { printf("marked-string [%.*s]\n", yyleng - 2, yytext + 1); if (YY_START == INITIAL) BEGIN(SUCCESSION); }
<<EOF>>     { if (YY_START == INITIAL) { yyerror("unexpected EOF"); return 1; } else return 0; }

\(\)        { yyerror("null string between parentheses"); return 1; }
\([^)]*\(   { yyerror("illegal left parenthesis"); return 1; }
\([^)]*     { yyerror("unexpected EOF"); return 1; }
\)          { yyerror("illegal right parenthesis"); return 1; }

規則部だけを変更した。随分コンパクトになった。
変数YY_STARTに現在の開始状態が入っており、二つの開始状態の区別は単純にINITIALか否かの判断で行える。
アクション内の開始状態による差異がある三部分をこの方法で処理分けした。
これで全ての規則を両開始状態で共通化できたので、パターンの<...>による書き分けが不要になった。

これは開始状態を入力を受けたかどうかのフラグとして利用しているだけなので、
別に新たな開始状態を定義したりしなくても、フラグを自分で用意しても構わない。
が、開始状態を使うと短く書けるのでこれでもいいと思う。