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); }
© Copyright 2024 ExpyDoc