FlexとBison+アルファ -実習編東京工科大学 コンピュータサイエンス学部 亀田弘之 内容 1. 実例紹介 2. 基礎練習 – FlexとBisonの書き方・実行手順 3. 実習1 – HTMLのタグを抜き出す 4. 実習2 – 電卓作成 5. 実践的演習 – Pascalパーザ作成 1.実例紹介 2.基礎練習 • Flexの書き方・実行手順 Flex書き方 %% %% Flex書き方 各種定義 %{ C言語のコード %} %% Flexの記述 パターン アクション の列 %% C言語のコード 実行手順 ライブラリ(fl) Flex Program Flex Lex.yy.c 文字列入力 gcc a.exe 出力 7 電卓作成 解説文 概要 簡単な電卓ソフトウェア。 例えば、1+2 と入力すると、計算結果として 3 を表示する。 (1+2)*4 ならば 12、 1+2*4 ならば 9 と表示する。 ただし、変数は使えない。 機能: キーボードから入力された数式(変数や四則演算以 外の関数は含まないもの)に対して、 その計算結果を画面に出力する。 使い方: 起動方法:コマンドラインにおいて、calc と入力する。 数式入力方法:キーボードから入力する。 プログラムの説明 lexer.l の説明 機能の説明 Flex (Fastlex ) のプログラムで、数式の構文構成要 素 (token) を切り出すプログラムを 自動生成する。生成されるプログラムはC言語で 書かれたものとなる。 ソースコードの説明 大きく3つの部分から構成されている。 1) ヘッダー等の情報 2) トークンの認識・切り出し 3)C言語のソースコード parser.yの説明 機能の説明 数式の構文解析を行う。このソースプログラムを Bisonで処理すると、 C言語で書かれた簡易電卓プログラムが生成され る。 電卓作成(2) コンパイルの仕方と動作例 % bison -d parser.y % flex lexer.l % gcc -o calc parser.tab.c -lfl % ./calc.exe 1: 1 + 2 3 2: (1+2)*4 12 3: ソースコード(lexer.l) %{ #include "parser.tab.h" #include <stdio.h> int tokenValue = NONE; int lineNumber = 1; %} %% [ \t]+ { /* do nothing */ } \n { return(ENDOFLINE); } [0-9]+ { tokenValue = strtol(yytext, NULL, 10); return(NUMBER); } "+" { return(PLUS); } "-" { return(MINUS); } "*" { return(MULTIPLY); } "/" { return(DIVIDE); } "(" { return(LPAR); } ")" { return(RPAR); } . { tokenValue = yytext[0]; return(NONE); } %% ソースコード(parser.y) %{ extern int tokenValue; extern int lineNumber; #define prompt printf("\n%5d : ", ++lineNumber) %} %start lines %token PLUS MINUS MULTIPLY DIVIDE LPAR RPAR NONE ENDOFLINE NUMBER %% lines : | ; /* null string epsylon */ expression { printf("%d", $1); prompt; } ENDOFLINE lines expression | | ; : expression PLUS term { $$ = $1 + $3; } expression MINUS term { $$ = $1 - $3; } term { $$ = $1; } term : | | ; term MULTIPLY factor { $$ = $1 * $3; } term DIVIDE factor { $$ = $1 / $3; } factor { $$ = $1 } factor : | | ; LPAR expression RPAR { $$ = $2; } NUMBER { $$ = tokenValue; } MINUS NUMBER { $$ = -tokenValue; } %% #include "lex.yy.c" main(){ printf("%5d : ", lineNumber); yyparse(); return 0; } yyerror(char *s){ printf("%s\n", s); } コンパイラの動作概要 • 結局コンパイラはどう動いているのか? 概要を理解しよう (教科書2.3 p.15~19 を参照のこと) プログラムの一部(Pascal言語) Program example; Var abc, e3, fg: real; Begin abc := e3*2.56 + abc/e3; end abc := e3*2.56 + abc/e3; の処理 変数名表(1) 番号 変数名 データ型 アドレス 0 1 演算記号表(8) 2 番号 演算 0 := 1 + 2 - 0 3 * 1 4 / 定数表(2) 番号 2 変数名 データ型 アドレス abc := e3*2.56 + abc/e3; の処理 変数名表(1) 演算記号表(8) 番号 変数名 データ型 アドレス 番号 演算 0 abc real 100 0 := 1 e3 real 104 1 + 2 fg real 108 2 - 3 * 4 / 定数表(2) 番号 変数名 データ型 アドレス 0 2.56 real 500 1 2 出力:(1,0)(1,1)(2,0)(8,3)(1,0)(1,1)(8,4)(8,1)(8,0) スタック _(8,1)(8,1 )(8,4) その他参考コード 1. 2. 3. 4. (コード1) lexer.lとparser.y (コード2) lexer2.lとparser2.y (コード3) lexer3.lとparser3.y (コード4) lexer4.lとparser4.y (Webページに挙げてあります。) 試験へ向けて • 教科書の 3.1 バッカス記法 と 3.2 構文図式 は、試験に出ます。勉強しておいてください。
© Copyright 2024 ExpyDoc