コンパイラ演習資料(javacc      担当:佐々木晃

□演習問題B0(締め切り=2009/06/15演習中の回収時)

問題番号: B0

課題名:コンパイラの作成準備

出題日:06/08

課題:JavaCCの設定と準備

本演習資料にしたがって、中置記法による算術式(四則演算、括弧が使える)を逆ポーランドによる式に変換するプログラム

JavaCCを用いて作成せよ。

備考:コンパイラ作成演習のガイドラインに従って、アップロードしてください。

 

(参考、コンパイラ作成1)

http://cis.k.hosei.ac.jp/~asasaki/lect/compiler/2008A/problem/problem1.htm

 

 

0.    javaccについて。

詳しくは、中田先生のページを参照

http://cis.k.hosei.ac.jp/~nakata/lectureCompiler/JavaCC/index.html

その他、http://cis.k.hosei.ac.jp/~asasaki/lect/compiler/JavaCCの項目を参考にせよ。

1.    javaccのインストール (Eclipse-pluginを利用)

説明は下記にある。

Eclipse JavaCC Plugin Home

http://eclipse-javacc.sourceforge.net/

 

下記からダウンロード

SourceForge.net: JavaCC Eclipse Plugin

http://sourceforge.net/projects/eclipse-javacc

←少し古いバージョン

 

 

インストール。アーカイブを展開(解凍)した中には、featurespluginsというフォルダが含まれる。

この中身を利用しているEclipseのルートフォルダにあるfeatures, pluginsのそれぞれに入れてやればよい。

展開したJavaCC Eclipse-Pluginに含まれる、features

pluginsの中身を利用しているEclipseのフォルダにコピー

 

ここにDrug and Dropすればよい。

 

 

以上で終了

 

2.    プロジェクトとJavaCCオプションの設定

ここではCompilerConstructionというプロジェクトを設定。通常と同じくJavaプロジェクトを指定。

 

 

JavaCCのオプションの設定。

 

自動セーブ機能をOFF(好みで)

 

 

 

Javaのバージョンを1.5 (必須)

 

 

 

3.    コンパイラ(構文解析器)の作成の流れ

準備:テンプレート作成

(ただし、ここでは実際には作成されたテンプレートは全く使わない)

 

 

 

A:JJファイルを編集:

ここでは、テンプレートを完全に書き換えてプログラムを書く。

(本資料の「5:開発の流れ」のサンプルプログラム、あるいは配布プログラムのSample.jjの内容で説明する。)

 

B:コンパイラの自動生成: JavaCCでコンパイラ(構文解析器)を自動生成する。

 

C:生成されたコンパイラ(構文解析器)のコンパイル:

実際には、Sample.jjにはバグがあるので、自動生成の段階でエラーがでるので、直さないと先には進めない。(後述)

Sample.jjのバグを取り除いたあと、Sample.java(自動生成されたコンパイラ)をコンパイルする。下記のようなエラーになればコンパイルは一応成功している。(コンパイルするべきプログラムがmainの引数に与えられていないために出ているエラーである。)

Sample.jjから自動生成されたコンパイラ(構文解析器)Javaファイル。うまく、自動生成できないときは、refreshする意味で、以前に生成されたものを削除すると良い。

 

 

 

D(1):ソースコードの作成

作成したコンパイラに読み込ませるソースコードを用意する。

ここではb0というフォルダを用意して、sample1.txtにソースコードを書く。

 

D(2) 作成したコンパイラを実際に動かす。

 

引数にコンパイルしたいファイル名を書く。(さきほどの1234 +2345をコンパイルする。)

 

 

 

コンソールに下記が表示されたら成功。

 1234 2345 +

 

4.    コンパイラ作成の流れ

A. jjファイルを編集、作成。(上の例ではSample.jj

B. コンパイラの生成 jjファイルに誤りがあると、先には進まないのでAにもどる。)

 成功すると Sample.javaが作られる。

C. Sample.javaのコンパイルと実行

 Sample.javaのコンパイルに成功すると、コンパイラが起動する。

 ただし、Sample.jjのアクションの部分などに誤りがあった場合、Sample.javaをコンパイルすることはできないので、Aに戻る。

D. 実際にコンパイラの動きを試す。動きがおかしいときはAに戻る。

 

5. 開発の例:

version 1

4A. サンプルプログラムSample.jj(わざと誤りが入れてある)の作成

options {

 JDK_VERSION="1.5";

}

 

PARSER_BEGIN(Sample)

import java.io.*;

/*

Sample

  Tokens:

    <NUMBER> = {0|1|2|3|4|5|6|7|8|9}+

    <PLUS> = "+"

  Grammar:

    E ::= E <PLUS> F | F

    F ::= (E) | <NUMBER>

 

-> eliminating left recursion of the grammar

    E ::= F E'

    E' ::= <PLUS> E' F | epsilon

    F ::= (E) | <NUMBER>

*/

 

public class Sample {

  public static void main(String args[]) {

    try {

       Sample parser = new Sample( new FileReader(args[0] ));

       parser.start();

    }catch(Exception ex){

    ex.printStackTrace();

    System.err.println("Failed to parse:"+ex.getMessage());

    }

  }

}

PARSER_END(Sample)

 

SKIP:{

     <SPACE: " "|"\t">

     | <NL:"\n"|"\r"|"\r\n">

}

 

TOKEN:{

     <NUMBER:(["0"-"9"])+>

     <PLUS: "+">

}

 

void start(): {}

{

  e()

}

 

void e():{}

{

  f() e2()

}

 

void e2():{}

{

  <PLUS> f() {System.out.pritn(" +");} e2()  /* 誤り */

  | {}

}

 

void f():{Token token;}

{

  token=<NUMBER> {System.out.print(" "+ token.image);}

}

 

 

4B. コンパイラの自動生成

jjファイルの記述誤りがあるのでエラーがでる。

 

version 2

4Ajjファイルを修正しVersion 2を作る。

「|」を加えると直る。上記43行目の <Plus>の前。

 

4B:コンパイラの生成→成功

 

 

4C 生成されたコンパイラのコンパイルと実行

Sample.javaに赤×印がついているが、生成されたJavaファイルに誤りがある。printのつづりあやまり。もとのjjファイルを直す必要がある。

version 3

 

4Ajjファイルを修正

4B: コンパイラの自動生成→成功

→成功

4C4D 生成されたコンパイラのコンパイルと実行

「3.コンパイラ(構文解析器)の作成の流れ」のDの項に書いた方法で、ソースプログラムを用意した後、実際に作成したコンパイラを動かしてみる。

サンプルテキスト、sample1.txt

1234+2345

実行結果(コンソールに出力される)

1234 2345 +

 

6. 配布したサンプル

配布したサンプルに含まれるjavaccsamples以下のjjファイルおよびtxtファイルの説明

□字句解析のテスト→ScannerSample1.jj

このテストは、標準入力(System.in)から入力するので、実行する際には引数は必要なし。

実行するとコンソールで入力待ちになるので、テキストを入力する。(Enterを押さないと入力は処理されない。)

□算術式を逆ポーランドに翻訳するプログラム

l         Sample.jj 上述のエラーのある例。修正したものがSample1.jj

l         Sample1.jj 足し算その1

サンプルソースプログラムは、sample11.txt, sample12.txt

l         Sample2.jj 足し算その2

サンプルソースプログラムは、sample11.txt, sample12.txt

l         Sample3.jj 括弧を扱えるようにする。

サンプルソースプログラムは、sample11.txt, sample31.txt

l         Sample4.jj 引き算を扱えるようにする。

  サンプルソースプログラムは、sample11.txt, sample41.txt

l         Sample5.jj 掛け算を扱えるようにする。

  サンプルソースプログラムは、sample11.txt, sample51.txt