プログラミングユーティリティ

アクション

スキャナは、規則の開始部にある正規表現に一致する文字列を認識すると、その規則の右側を検査してアクションを実行します。ユーザーは、このアクションを指定します。

見つかったトークンの型とその値を記録する、トークンを別のトークンと置換する、トークンまたはトークンの型のインスタンス数 (出現する数) をカウントする、などがアクションとして考えられます。これらのアクションは、C のプログラムとして作成します。

アクションは、任意の数の文を使用して構成できます。何らかの方法でテキストを変更したり、テキストが見つかったことを示すメッセージを出力したい場合があります。たとえば、式 Amelia Earhart を認識して、認識したことを通知するには、以下の規則を適用します。

"Amelia Earhart" printf("found Amelia"); 

テキスト内の長い医学用語を同義の略語に置換する処理は、以下のような規則で実現できます。

Electroencephalogram printf("EEG"); 

テキスト内の行数をカウントするには、行の終わりを認識して、行カウンタを増分します。

lex では、復帰改行を表す ¥n などの、標準の C エスケープシーケンスを使用します。たとえば行数をカウントするには、以下のような構文を使用できます。ここで使用している lineno は、他の C 変数と同じようにして、「定義」で宣言されています。

¥n  lineno++; 

C 言語の NULL 文 (1 個のコロン ;) を指定すると、入力は無視されます。したがって、以下の規則を使用した場合には、空白文字、タブ、復帰改行は無視されます。

[ ¥t¥n] ; 

また、択一演算子 | は、ある規則とその次の規則のアクションが同じであることを表す際に使用することもできます。たとえば、前述の例は以下のように記述しても同じ結果になります。

" " | 
¥t
¥n ;

スキャナは、式と一致したテキストを yytext[] という文字配列内に格納します。必要に応じて、この配列の内容を出力したり操作できます。実際に、lexprintf ("%s", yytext) と同義の ECHO というマクロを備えています。

C 言語の長い文または複数の文でアクションを構成する場合には、その文を複数の行に渡って記述できます。アクションが、1 つの規則だけに対するものであることを lex に伝えるには、その C コードを中括弧で囲みます。

たとえば、数字列が見つかるごとにその数字列とそれまでに見つかった数字列の総数を出力しながら、入力テキスト全体の数字列の総数をカウントするには、次のような lex コードを使用します。

¥+?[1-9]+      { digstrngcount++; 
                 printf("%d",digstrngcount); 
                 printf("%s", yytext); }

? は、その直前の文字が 0 個または 1 個存在することを表しているので、この仕様は 0 個または 1 個のプラス記号が直前に付いた数字列と一致します。また、負の数字列の場合でも、マイナス記号の後の部分はこの仕様に一致するので、同様に数値が捕捉されます。