コンパイラ生成系

コンパイラ生成系
flex
•
•
•
•
字句解析器生成系
入力ファイル: 字句定義、拡張子.l
lex.yy.cを生成(後述のyaccでincludeする)
コンパイル: flex ファイル名
flexの書式
定義部
%%
ルール部
%%
ユーザ定義関数
定義部: ヘッダ
– ヘッダ:生成されるCファイルの先頭に挿入される
– 定義:正規定義(正規表現のマクロ定義)
ルール部:字句の正規定義
– int yylvalはyaccから参照できるグローバル変数
– { }内にCコード記述、(含return文)
– 字句の値をreturnし、yacc側でトークンとして読む
ユーザ定義関数:上記Cコード内で利用する関数を記述
yacc
•
•
•
•
構文解析器生成系
入力ファイル:主に構文定義、拡張子.y
y.tab.cを生成する
字句解析器はflexの出力をインクルードする。
– flexライブラリをリンク
• コンパイル: yacc ファイル名
yaccの書式
宣言部
%%
ルール部
%%
ユーザ定義関数
定義部: ヘッダ
– ヘッダ:生成されるCファイルの先頭に挿入される
• #include “lex.yy.c”もここで
– main関数もここに書く
• yyparse()を呼んで解析開始
ルール部:文法の規則(および評価値割り当て)
– { }内にCコード記述
– Cコード内で評価値参照
• $$ ---- 左辺非終端記号の評価値(左辺値)
• $n ---- 右辺n番目の記号の評価値
ユーザ定義関数:上記Cコード内で利用する関数を記述
yacc出力のコンパイル
• cc y.tab.c –lfl #flexの場合
• cc y.tab.c –ll #lexの場合
練習課題(変数付き電卓)
• calcを改造して
– calc.lで代入の記号=と変数のトークンIDを追加
– calc.yで
• 代入の構文 ID=式を追加し
• 式の値を変数(IDの文字列名)に関連付けて記憶し
• 式の中で変数が利用できるようにする