言語理論とコンパイラ

第五回: 字句解析ツール flex

2012 年 5 月 18 日

http://www.sw.it.aoyama.ac.jp/2012/Compiler/lecture5.html

Martin J. Dürst

AGU

© 2005-12 Martin J. Dürst 青山学院大学

今日の予定

前回までのまとめ

全て同じ力を持って、お互いに変換可能、正規言語を定義・受理

コンパイラの段階

字句解析 (lexical analysis)

構文解析 (parsing; syntax analysis)

意味解析 (semantic analysis)

最適化 (optimization)

コード生成 (code generation)

コンパイラの構造

字句解析の実装

主な要点:

選択肢:

字句解析の自動化

flex の概要

cygwin の使い方

cygwin とハードディスク

flex の動作

flex の使い方

  1. 独自のファイル処理 (正規表現によるファイルの一部の認識・変更):

    main から yylex() 関数を一回呼ぶ

  2. 構文解析から呼ばれる字句解析:

    構文解析から yylex() を繰り返し呼んで、トークンを return で返す

今日の演習・宿題では 1.、bison で字句解析を作る演習では 2.を使用

flex の入力形式

flex 専用の指示と C プログラムの一部分が混在

主に、二つの %% で区切られている三つの部分からなる:

  1. 前文 (変数の定義と初期化、良く使う字句の定義など)
  2. 字句規則とその場合に実行するプログラムの断片
  3. そのほかの関数など

C 言語そのものと違って、改行、字下げが解釈を左右

flex の入力形式の骨格

宣言など (C 言語)
宣言など (C 言語)
%%
正規表現    実行文 (C 言語)
正規表現    実行文 (C 言語)
正規表現    実行文 (C 言語)
%%
関数など (C 言語)
関数など (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 の入力形式の構造

二回の %% で三つの部分に分割:

flex の演習 1

前のスライドの flex 用プログラムを処理、実行

  1. 前のスライドの flex 用プログラムを test.l にコピー
  2. > flex test.llex.yy.c を作成
  3. > gcc lex.yy.ca.exe を作成
  4. > ./a <file でプログラムを実行

flex の勉強の仕方

flex の基本動作

 

flex の演習 2

一般のテキストを XML の要素の内容にする場合には次の表に示される変換が必要
flex でその変換と逆変換のプログラムをそれぞれ作成

テキスト XML
' &apos;
" &quot;
& &amp;
< &lt;
> &gt;

flex の演習 3: 数字の発見

入力をそのまま出力、しかし数字でしたら、その前に >>>、その後に <<< をつけるプログラムを flex で作成

入力例:

abc123def345gh

出力例:

abc>>>123<<<def>>>345<<<gh

ヒント: 正規表現でつかんだ文字列は yytext として使用可能

flex の演習 4: 日付 C の字句解析

提出期限と場所: 2012 年 5 月 31 日 (木) 19:00 まで O 棟 5 階の O-529 号室の前の箱に投入

提出形式:

プログラミング言語 C の字句解析プログラムを作成。出力はトークン一つに一行で、トークンの種類も記述。

処理するトークンは以下の通り:

発展問題 (追加点): 追加のトークン類: 文字列定数、コメント

演習 4: 入力と出力の例

入力の簡単な例:

if (xyz*3 > 5) abc = 'c';

出力の例:

keyword: if
parenthesis: (
identifier: xyz
operator: *
integer constant: 3
operator: <
integer constant: 5
parenthesis: )
identifier: abc
operator: =
character constant: 'c'
semicolon: ;

flex でよく出る問題

宿題のヒント