Go to the first, previous, next, last section, table of contents.


構文解析器のデバッグ

もし、Bison文法ファイルが正しくコンパイルされたのに、 生成された構文解析器が思いどおりに動かない場合には、 yydebug構文解析器追跡機能が、調査の役に立つでしょう。

追跡機能のコンパイルを有効にするためには、 構文解析器をコンパイルするときに、マクロYYDEBUGを定義する必要があります。 そのためには、コンパイラのオプションに`-DYYDEBUG=1'を指定するか、 あるいは、文法ファイルのC宣言部に`#define YYDEBUG 1'と書いておく 必要があります(see section C宣言部)。 あるいは、Bisonを実行するときに(see section Bisonの実行)、 `-t'オプションを指定しておくと、 YYDEBUGが定義され、追跡が可能になります。

追跡機能はstderrを使うので、C宣言部に #include <stdio.h>と書いておく必要があります。

追跡機能付で構文解析器をコンパイルしたら、構文解析器の実行時に、 追跡機能を有効にするために、yydebug変数を0でない値にしてください。 C言語のプログラム(おそらくmain関数の中)でこの変数に代入するか、 あるいは、デバッガでこの変数の値を変えればいいでしょう。

yydebugが0でない場合、構文解析器はそれぞれの段階で、 1行まはた2行の追跡情報を生成し、stderrに出力します。 追跡情報には、次のような情報が含まれています。

この情報を理解するためには、Bisonに`-v'オプション (see section Bisonの実行)を付けて実行すると生成される 明細ファイルが参考になるでしょう。 このファイルには、さまざまな規則の中での位置による表現で 各状態の意味が示され、また、 各状態がそれぞれの可能な入力トークンによって どのように動作するかが示されています。 連続する追跡の意味を読むことによって、 明細ファイルで仕様が示されている構文解析器の機能について、理解できるでしょう。 何か望ましくないことが起きている部分を確認すれば、 文法ファイルのどこに問題があるかわかるでしょう。

構文解析器ファイルはC言語のプログラムなので、 Cのデバッガを使えますが、 何が起きているか調べることは困難です。 構文解析器関数は、有限状態機械インタープリタで、 アクションが実行されると、 プログラムの同じ部分が何度も何度も実行されます。 実用的なのは文法の中で変数の値を調べることだけでしょう。

デバッグ情報には、通常、それぞれのトークンのトークン型だけが含まれ、 トークンの意味値は含まれません。 マクロYYPRINTを定義することで、 トークンの意味値を表示させられます。 YYPRINTの定義には、3個の引数がともないます。 構文解析器は、YYPRINTに、標準入出力ストリーム、 トークン型の数値番号、トークンの値(yylvalによる)を渡します。

多機能電卓に適するYYPRINTの例を示します (see section mfcalcのための定義)。

#define YYPRINT(file, type, value)   yyprint (file, type, value)

static void
yyprint (file, type, value)
     FILE *file;
     int type;
     YYSTYPE value;
{
  if (type == VAR)
    fprintf (file, " %s", value.tptr->name);
  else if (type == NUM)
    fprintf (file, " %d", value.val);
}


Go to the first, previous, next, last section, table of contents.