コマンド
lex
字句解析パーサ生成プログラム
最終更新
lex は「『字句解析を行うプログラムのソース』を生成するプログラム」である。プログラミング言語や設定ファイルの読み込み時に、lex で字句解析を行い、yacc で構文解析を行うのがよくあるパターンである。
●lex コマンドの使い方
入力された文字列が数値かアルファベットかを判定するプログラムを作って簡単な例を示そう。下記の内容の sample.l というファイルを作成する。
%{
#include <stdio.h>
%}
%%
[\t ]+ { /* 何もしない */ }
[0-9]+ { printf("digit=%s\n",yytext); }
[a-z]+ { printf("alphabet=%s\n",yytext); }
\n { /* 何もしない */ }
. { printf("Syntax error\n"); }
%%
そして、
とすると、lex.yy.c というファイルが作成される。つまり、lex は「C のソース生成器」なわけだ。次に、このソースを
でコンパイルする。-ll は libl.a という lex 用のライブラリをリンクするためのオプションである。コンパイルできたら実行してみよう。
% ./a.out
123 (と入力)
digit=123
abc (と入力)
alphabet=abc
! (と入力)
Syntax error
123 456 abc (と入力)
digit=123
digit=456
alphabet=abc
a1b2 (と入力)
alphabet=a
digit=1
alphabet=b
digit=2
なんとなくそれなりに処理されている気がする。
さて、sample.l をもう一度見てみよう。このファイルは
という構造になっている。定義部には規則部で使う変数・構造体の宣言や、#define・#include など、マクロやインクルードファイル関連を記述する。
一方、規則部には、
を並べておく。正規表現がマッチしたときに、対応する {} 内の部分が実行される。マッチした文字列は yytext という変数に代入される。
sample.l の規則部は、
- スペースやタブなら何もしない
- 0〜9 が連続する文字列なら、digit=… と表示
- a〜z が連続する文字列なら、alphabet=… と表示
- 改行コード (\n) なら何もしない。
- それ以外の文字は Syntax error を表示
という意味である。
この例のように lex 単体で使ってもよいが、yacc と組み合わせて使うと簡単なインタプリタくらいなら手軽に作ることができる。
●関連コマンド
より高機能かつ高速な字句解析器として flex コマンドがある。FreeBSD では flex が標準でインストールされており、/usr/bin/flex と /usr/bin/lex はハードリンクされている。Linux でも flex を使うのが一般的であろう。
lex で行えるのは字句解析のみである。構文解析を担当する yacc または yacc のオープンソース版である GNU bison と組み合わせて使うことが多い。
●余談
lex は 1970年代に UNIX に実装された。lex の開発者のひとりが、元 Google CEO のエリック・シュミットである。
読み方
lex
(UNIXコマンド) [れっくす]
字句解析部を自動生成するコマンドで、"LEXical" から名付けられた。