yacc 文法ファイル

yacc コマンドを使用してパーサーを生成するには、 入力データ・ストリームと、パーサーがデータをどのように処理するかを記述する文法ファイルを、そのコマンドに指定してください。

文法ファイルは、入力構造体を記述する規則、 これらの規則を認識したときに起動すべきコード、 および基本入力を行うサブルーチンから成ります。

yacc コマンドは、文法ファイルの情報を使用して、 入力プロセスを制御するパーサーを生成します。 このパーサーは、入力サブルーチン (字句解析プログラム) を呼び出して、 入力ストリームから基本項目 (トークン と呼ばれる) をピックアップします。 トークンは、入力サブルーチンがどのパターンを送信しているかをパーサーに伝える記号または名前です。 非終端記号は、パーサーが認識する構造体です。 パーサーは、これらのトークンを文法ファイル内の構造体規則に従って編成します。 構造体の規則は、文法規則 と呼ばれます。 パーサーは、これらの規則の 1 つを認識すると、 その規則のために準備されたユーザー・コードを実行します。 このユーザー・コードは、アクション と呼ばれます。 アクションは値を戻し、他のアクションによって戻された値を使用します。

C プログラミング言語を使用して、 アクション・コードやその他のサブルーチンを作成します。 yacc コマンドは、 文法ファイルに多くの C 言語構文規則を使用します。

main および yyerror サブルーチン

パーサー用に main および yyerror サブルーチンを準備する必要があります。 はじめて yacc コマンドを使用する場合でも 簡単に使えるように、yacc ライブラリーに mainyyerror サブルーチンの基本版が入っています。 ld コマンド (または cc コマンド) に -ly 引数を用いてこれらのサブルーチンを組み込みます。main ライブラリー・プログラムのソース・コードは、次のとおりです。
#include <locale.h>
main()
{
     setlocale(LC_ALL, "");
     yyparse();
}
yyerror ライブラリー・プログラムのソース・コードは、次のとおりです。

#include <stdio.h>
yyerror(s)
        char *s;
{
        fprintf( stderr, "%s¥n" ,s);
}

yyerror サブルーチンに対する引数は、 エラー・メッセージ (通常は文字列 syntax error) の入った文字列です。

これらのプログラムは限定されるので、これらのサブルーチンに関数を追加してください。 例えば、入力行番号をトラッキングして構文エラーが検出されたときに、メッセージと一緒にその行番号を印刷します。 外部整変数 yychar の中の値を使用することもできます。 この変数には、エラー検出時のルック・アヘッド・トークン番号が入っています。

yylex サブルーチン

ユーザーが文法ファイルに提供する入力サブルーチンには、以下の機能が必要です。

  • 入力ストリームを読む。
  • 入力ストリーム内の基本パターンを認識する。
  • パターンを、 パーサーに対してパターンを定義するトークンとともにパーサーに渡す。

例えば、入力サブルーチンが入力ストリームを WORD、NUMBER、および PUNCTUATION のトークンに分離して、次のような入力を受け取るとします。

I have 9 turkeys.

プログラムは、以下の文字列とトークンをパーサーに渡すようにすることができます。

文字列 トークン
I WORD
have WORD
9 NUMBER
turkeys WORD
. PUNCTUATION

パーサーは、入力サブルーチンによって渡されたトークンの定義を含んでいる必要があります。 yacc コマンドに -d オプションを指定して使用すると、 y.tab.h という名前のファイルの中にトークンのリストを生成します。 このリストは、字句解析プログラム (yylex) がパーサーと同じトークンを使用できるようにする、一連の #define ステートメントです。

注: パーサーとの矛盾を避けるために、英字 yy で始まるサブルーチン名を使用しないでください。

lex コマンドを使用して入力サブルーチンを生成するか、 または C 言語でルーチンを作成することができます。