Bisonについて


Bisonは BNFとそれに対する動作記述から、 構文解析系(パーサ)を自動生成するプログラムです。 Bisonのソースファイル(通常 .yという拡張子をつける)は、 次のように書きます。 (これは通常の四則演算と、さらに単項の「-」記号を持つ文法です。)
%{
 /* C宣言部 ─ 動作記述の中で用いる関数の定義や宣言 */
#include <stdio.h>
#include <ctype.h> /* isdigitのため */
void yyerror(char* s) { /* エラーがあった時に呼ばれる関数を定義しておく */
   printf("%s\n", s);
}
%}
 /* Bison宣言部 */
%union {
 /* 各文法記号の``値''となりうる型を C言語の unionで表す。

    この例の場合 NUMBERという終端記号と exprという非終端記号は、
    double型の``値''を持っているので、double dval;は必要。
    また、この例題の場合 int ival;は不要だが、例として示しておく。
  */
  int    ival;  
  double dval;
}
 /* 終端記号と非終端記号の宣言 */
 /* <dval>はその文法要素が double型を持つことを宣言する
    (上の union宣言参照) */
%token <dval> NUMBER 
%token EOL
%type  <dval> expr
 /* 演算子の優先順位と結合性の宣言 */
%left '+' '-'
%left '*' '/'
 /* leftは左結合を表す、下の演算子ほど優先順位が高い */
%right UMINUS
 /* UMINUSは優先順位の指定だけに使われる文法記号 */


%%
 /* 文法記述とそれに対する動作 */
input	:	/* 空 */
	| input line	{}
	;
line	: EOL		{ exit (0); }
	| expr EOL	{ printf("%g\n", $1); }
	;
   /* $$は左辺の値、$nは右辺の n番目の文法要素の値を表す。 */
expr	: NUMBER	{ $$ = $1; }
	| expr '+' expr	{ $$ = $1 + $3; }
	| expr '-' expr	{ $$ = $1 - $3; }
	| expr '*' expr { $$ = $1 * $3; }
	| expr '/' expr	{ $$ = $1 / $3; }
	| '(' expr ')'	{ $$ = $2; }
	| '-' expr %prec UMINUS	{ $$ = - $2; /* %prec以下は優先順位を表す。*/}
	;
%%

 /* yylex関数を flexを使わず自分で定義している。*/
int yylex() {
  int c;

  do {
     c = getchar ();
  } while (c == ' ' || c == '\t');

  if (isdigit (c) || c == '.') {
    ungetc(c, stdin);
    scanf("%lf", &yylval.dval);
    /* ``値''は yylvalという 大域変数に代入して返す。*/
    return NUMBER;
    /* NUMBERというトークンを返す。*/
  }

  if (c == '\n') {
    return EOL;
  }
  if (c == EOF) {
    return 0; /* 終了を表す。*/
  }
  /* 上のどの条件にも合わなければ、文字をそのまま返す。*/
  return c;  
}

int main() {
   yyparse(); /* Bisonが生成した関数 */

   return 0;
}

/* 
   この例では、mainを自前で用意しているが、通常は他のファイルに
   main関数など他の関数を定義する。
 */

このファイル(ファイル名を parser.yとする)から Cソースファイルを生成するには
  bison parser.y
というコマンドを実行します。 これで parser_tab.cという名前 (.yファイルの名前の後ろに _tabがつく)の Cソースファイルができます。 また、-oというオプションで、 Cのファイル名を指定することができます。例えば、
  bison -ofoo.c parser.y
foo.cという名前の Cソースファイルができます。

この例の場合は、この Cソースファイルを普通にコンパイルすると、 実行可能ファイルができます。


システムプログラム 99のホームページ
Koji Kagawa (kagawa@eng.?????)