第五回: 中間テスト、flex の演習
2009 年 5 月 15 日
http://www.sw.it.aoyama.ac.jp/2009/Compiler/lecture5.html
© 2005-9 Martin J. Dürst 青山学院大学
flex
の概要flex
の使い方と演習全て同じ力を持って、お互いに変換可能、正規言語を定義・受理する
ls
: ディレクトリの内容をリストアップmkdir
: 新しいディレクトリを作るcd
: 現在のディレクトリを変更するpwd
: 現在のディレクトリを表示するgcc
: C のプログラムをコンパイルする./a
: コンパイルしたプログラムを実行するnotepad filename.l &
: cygwin
からメモ帳を直接、しかも並行に使える用に立ち上げるcygwin のインストール先が例えば C:\cygwin
だとすると、cygwin はまずそこの下しか見せない。
ユーザ用のホームディレクトリは
C:\cygwin\home\user1
とかで、pwd
で
/home/user1
として表示される。
C:\cygwin
の下から脱出したい場合には cd
/cygdrive/c
でできます。
(昔は cygdrive
は秘密でしたが、最近は見えるようになりました)
flex
の概要lex
の GNU 版、様々な拡張lex
: lexical analyzer (作者の名前は Lesk)bison
と相性がよいflex
の動作.l
で終わる flex
用入力ファイルを作成 (例: test.l
)flex
で test.l
ファイルから
lex.yy.c
ファイルを作る:flex test.l
lex.yy.c
を (他のファイルと一緒に)
コンパイルするflex
の使い方main
から yylex()
関数を一回呼ぶ
構文解析から yylex()
を繰り返し読んで、トークンを return
で返すようにする
flex
の勉強の仕方flex
の出力 (lex.yy.c
) を読むflex
のソースを読む (flex
そのものの字句解析は flex
形式で書かれている)flex
-v
)flex
の入力の形式flex
専用の指示と C
プログラムの一部分が混在
主に、二つの %%
で区切られている三つの部分からなる:
その三つの部分の間に区切りとして %%
がある
flex
の入力の形式の一例int num_lines = 0, num_chars = 0; %% \n ++num_lines; ++num_chars; . ++num_chars; %% main() { yylex(); printf( "# of lines = %d, # of chars = %d\n", num_lines, num_chars ); } int yywrap () { return 1; }
flex
の演習 1前のスライドの flex
用プログラムをファイルにし、flex
と
gcc
を使って実行ファイルにし、実行してみる。
flex
の演習 2一般のテキストを XML
の要素の内容に入れたい場合には次の表に示される変換を行う必要がある。flex
でその変換と逆変換を行うプログラムをそれぞれ書く。
テキスト | XML |
' |
' |
" |
" |
& |
& |
< |
< |
> |
> |
flex
の演習 3: Ruby 用字句解析提出期限と場所: 2009 年 5 月 28 日 (木) 19:00 まで O 棟 5 階の O-529 号室の前の箱に投入
提出形式:
flex
の入力になる .l
ファイルRuby の次の字句を認識、一行ごとに出力:
種類 | 説明 | 例 | 出力 |
インスタンス変数 | 先頭に @ | @abc |
Instance variable: @abc |
クラス変数 | 先頭に @@ | @@def |
Class variable: @@def |
メソッド名 | 最後に !, ?, 又は = | nil? |
Method: nil? |
メソッドまたは局所変数 | 先頭が小文字 | my_var |
Method or variable: my_var |
グローバル変数 | 先頭は $ | $global |
Global variable: $global |
コンスタント | 先頭が大文字 | String |
Constant: String |
十新数の整数 | 先頭は 0d, 0D, 又は 0 意外 | 1_234 |
Decimal Integer: 1234 |
八進数 | 先頭は 0 | 0765 |
Octal Integer: 501 |
十六進数 | 先頭は 0x 又は 0X | 0xAB_D3 |
Hex Integer: 43987 |
二進数 | 先頭は 0b 又は 0B | 0b1010_1100 |
Binary Integer: 172 |
コメント | # から行末まで | # hello |
Comment: hello |
[エラー] | 空白類意外処理できない文字一つ | \ |
Error: '\' |
発展問題: Ruby の他の字句も対象 (例: 文字列、演算子、正規表現など)。