yaccで遊ぼう


 yacc は Yet Another Compiler Compiler の略で構文解析ルーチン(パーサ)を 生成するための一種のコンパイラで、構文解析アルゴリズムには LALR(1) を使用しています (ちなみにlexという字句解析ルーチンを生成するツールもあり yacc/lexと言う風に対で呼ばれることが多い)

 両者はWindows環境で動作するものも入手可能で、たとえばGNUのBisonとflexは それぞれyaccとlexに対応するソフトウェアです。

 今回は、あの純日本製のCコンパイラであるLSI−Cの開発で有名な 森 公一郎さんが フリーソフトとして公開されているkmyaccを使って簡単な電卓を作ってみました。

 kmyaccはvectorでも公開されていますので興味ある方はダウンロードして遊んでみては如何でしょうか?



1.今回作った簡易電卓の仕様
 対応する演算子は
  ・2項演算子:+−*/(四則演算)
  ・単項演算子:−
 その他
  ・( ) も使えます。
  ・変数の型は double
  ・10進数と16進数を混在した計算ができます。
   (16進数表現の数値は0で始める  例 089AB)


2.簡易電卓用構文解析定義ファイルの作成
  yaccファイル(calc.y)は3つのパートから成り、

     定義部
     %%
     規則部
     %%
     ユーザ定義サブルーチン部

 の構成となります。
 今回は字句解析にはlexを使用しないでユーザ定義部に直接C言語で記述しました。
 (calc.yはtab幅を4文字で設定して作っているのでブラウザで表示するとちょっと崩れて見えます^^;)

3.kmyaccを使ってコンパイル
 VCで作った簡単なGUI部分とリンク後、ディバッグし易くするため、 下記のように -l オプション付きでコンパイルします。

    kmyacc -l calc.y

 コンパイルが終了すると ytab.c が生成されます。


4.VCによる簡単なGUIの作成
 ダイアログベースの簡単なGUIを作成し、上記3項で生成された ytab.c とリンクします。
 ここで問題が一点発生しました。
 VC(Ver6.0)のバグなのか、*.cファイル内で使用している#ifdef〜#elseが正常に機能しません。

  たとえば

    #define AAA
    #ifdef AAA
    #define BBB 123
    #else
    #define BBB 456
    #endif

 とした場合、BBBが二重定義されているというワーニングがでます。ちなみにヘッダファイル(*.h)や C++ファイル(*.cpp)であれば問題ないようです。
 苦肉の対策として yacc が生成した ytab.c をヘッダファイルとしてVCのプロジェクトに追加しました^^;

 誰かこのCソース内での#ifdef〜#elseの挙動に関して情報が有りましたら是非教えてください。

 またyaccの定義ファイル内で構文エラーの時に使用する YYERROR を一度も使わないとコンパイルする時に yyerrlabラベルが未使用であるとのワーニングがでるようです。


5.完成した簡易電卓プログラムの外観

 プログラムはここからダウンロードできます(5,586bytes)。


簡易電卓の外観


6.参考文献
  yacc/lex プログラムジェネレータ on UNIX
  著者:五月女健治
  発行:テクノプレス


トップページへ  |   公開ソフトのぺいじへ