字句解析プログラムによって実行されるアクション
字句解析プログラムは、仕様ファイルの規則のセクションの拡張正規表現の 1 つを突き合わせる場合、拡張正規表現に対応するアクション を実行します。 入力ストリーム内のすべての文字列を突き合わせるだけの十分な規則がない場合、 字句解析プログラムは入力を標準出力へコピーします。 したがって、入力を出力へコピーするだけの規則は、作成しないでください。 デフォルト出力は、規則の食い違いを検出するのに役立つ場合があります。
lex コマンドを使用して、yacc コマンドが作成するパーサーへの入力を処理する場合は、すべての入力文字列を突き合わせる規則を提供します。 その規則は、 yacc コマンドが解釈できる出力を生成するものでなければなりません。
null アクション
[ ¥t¥n] ;
次のアクションと同じ
" " |
"¥t" |
"¥n" ;
¥n と ¥t の前後の引用符は必須ではありません。
一致した文字列の出力
[a-z]+ printf("%s",yytext);
C 言語の printf サブルーチンは、 フォーマット引数と印刷するデータを受け入れます。 この例では、printf サブルーチンに対する引数の意味は、次のとおりです。
- %s
- 印刷の前にデータをタイプ文字列に変換する記号
- %S
- 印刷の前にデータをワイド文字列 (wchar_t) に変換する記号
- yytext
- 印刷するデータの入った配列の名前
- yywtext
- 印刷するマルチバイト・タイプ (wchar_t) データが入っている配列の名前
[a-z]+ ECHO;
[a-z]+ printf("%s",yytext);
- %array
- yytext を null 終了文字配列として定義します。 これは、デフォルトのアクションです。
- %pointer
- yytext を null 終了文字列を指すポインターとして定義します。
一致した文字列の長さの検出
- yyleng
- 一致したバイト数をトラッキングします。
- yywleng
- 一致した文字列内のワイド文字の数をトラッキングします。 マルチバイト文字は、長さが 1 を超えています。
[a-zA-Z]+ {words++;chars += yyleng;}
このアクションは、一致したワードの中の文字数を合計して、 その数を chars に書き込みます。
yytext[yyleng-1]
文字列内の文字列の突き合わせ
she {s++; REJECT;}
he {h++}
¥n |
. ;
she のオカレンスをカウントした後で、 lex コマンドは入力文字列を拒否して、 he のオカレンスをカウントします。 he には she は組み込まれていないので、REJECT アクションは he には不要です。
yytext 配列への結果の追加
通常は、yytext 配列の中の現行項目は、入力ストリームのその次の文字列によって上書きされます。 yymore サブルーチンを使用した場合、 入力ストリームからの次の文字列は、yytext 配列の現行配列の最後に追加されます。
%s instring
%%
<INITIAL>¥" { /* start of string */
BEGIN instring;
yymore();
}
<instring>¥" { /* end of string */
printf("matched %s¥n", yytext);
BEGIN INITIAL;
}
<instring>. {
yymore();
}
<instring>¥n {
printf("Error, new line in string¥n");
BEGIN INITIAL;
}
複数の規則を突き合わせれば文字列は認識されるかもしれないけれども、 yymore サブルーチンを繰り返し呼び出せば、yytext 配列に確実に文字列全体を組み入れることができます。
入力ストリームへの文字の戻り
yyless(n)
ここで、n は保持すべき現在の文字列の文字数です。 文字列の中のこの文字数を超える部分の文字は、入力ストリームに戻されます。 yyless サブルーチンにも、 / (スラッシュ) 演算子が使用するのと同じタイプの先読み関数が用意されていますが、 こちらのほうがその使用法をさらに詳細に制御することができます。
=-[a-zA-Z] {
printf("Operator (=-) ambiguous¥n");
yyless(yyleng-1);
... action for = ...
}
入出力サブルーチン
- input()
- 次の入力文字を戻す
- output(c)
- 出力上に文字 C を書き込む
- unput(c)
- 文字 c を、後で input サブルーチンで読むように、 元の入力ストリームにプッシュする
- winput()
- 次のマルチバイト入力文字を戻す
- woutput(C)
- マルチバイト文字 C を、元の出力ストリームに書き出す
- wunput(C)
- マルチバイト文字 C を、後で winput サブルーチンで読むように、 元の入力ストリームにプッシュする
lex プログラムは、これらのサブルーチンをマクロ定義の形で提供します。 サブルーチンは、lex.yy.c ファイルの中にコーディングされています。 これらを変更して、他のバージョンを提供することができます。
winput、wunput、 および woutput マクロは、 yywinput、yywunput、 および yywoutput サブルーチンを使用するように定義されています。 互換性のために、yy サブルーチンは後に input、unput、および output サブルーチンを使用して必要なバイト数を完全なマルチバイト文字で読み取り、置き換え、 および書き込みをします。
- すべてのサブルーチンが同じ文字セットを使用する必要がある。
- input サブルーチンはファイルの終わりを示すために 0 の値を戻す必要がある。
- input サブルーチンに対する unput サブルーチンの関係は変更しない。変更すると、先読み関数が作動しなくなる。
lex.yy.c ファイルによって、 字句解析プログラムは最大 200 文字をバックアップすることができます。
ヌルの入ったファイルを読むには、 異なるバージョンの input サブルーチンを作成する必要があります。 通常バージョンの input サブルーチンでは、 戻された値の 0 (null 文字から) は、ファイルの終わりと入力の終わりを示しています。
文字セット
%T
%T
{integer} {character string}
{integer} {character string}
{integer} {character string}
%T
ファイルの終わり処理
字句解析プログラムは、ファイルの終わりに達すると、yywrap ライブラリー・サブルーチンを呼び出します。このサブルーチンは、入力の終わりで通常の折り返しを継続することを字句解析プログラムに示す、1 の値を戻します。
ただし、字句解析プログラムが複数のソースから入力を受け取った場合は、yywrap サブルーチンを変更します。 新しい関数は、 新しい入力を取得してから 0 の値を字句解析プログラムへ戻す必要があります。 0 の戻り値は、プログラムが処理を継続する必要があることを示します。
新バージョンの yywrap サブルーチンで字句解析プログラムが 終了したときに、要約レポートとテーブルを印刷するコードを組み込むこともできます。 yywrap サブルーチンは、yylex サブルーチンに強制的に入力の終了を認識させる唯一の方法です。