結局、字句解析を行ってもらうためにFlexに命令します。
lexではおなじみ、正規表現を利用してトークンを定義する。
つまり
ある正規表現 → やること
という変換表一覧を作って書いてやる。
それをlexに通すと自動的にLexerとしてlex.yy.cというファイルにしてくれます。
lexのファイルの形式
%{
・・・最初の部分(そのままレキシカルアナライザに書かれる)・・・
%}
%%
・・・定義部(対応表を書く)・・・
%%
・・・コード部(使わない)・・・
%%
定義部の部分に正規表現→行動の対応を書く。
最初の部分にはその処理に利用するヘッダであったりとか
その他にもyaccで作るヘッダを入れてみたり、名前を定義したりする(マクロ)。
すごい簡単な例
%option noyywrap %{ %} %% [0-9]+ {printf("VALUE=%s\n", yytext);} "+"|"*"|"-" {printf("OPT=%s\n" , yytext);} [ \t\n] ; . ; %% main(){ yylex(); }
最後の 「.」 はすべてのパターンに一致しなかったことを示す。
つまり判別するパターンは全部で3つです。
1.数字
数字の場合、lexして取ってきた物(勝手にyytextに代入されている)を出力。
2.演算子+と*と−
文字をそのまま出力
3.スペース及びタブ及び改行は無視する
[ \t\n] ;
といったことが書いてあります。
最後のmainを書くことで、この部分が出力されるファイル lex.yy.cに出される。
これをコンパイルすることでレキシカルアナライザを実行できる。
実行手順
@:flex calc.l
@:gcc -o cl lex.yy.c
@:cl < sample例えばsampleに 「4-3」 と書いておくと次のように出力されます。
cl < sample
VALUE=4
OPT=-
VALUE=3
最初に4という値、次に演算子-、最後に値3が入ってくる
というのが字句分析の結果です。
これをもっと上手く使うとコンパイラに流用できるよっていうお話らしい。
難しいね。