yacc のアクション

それぞれの文法規則を用いて、 パーサーが入力ストリーム内で規則を認識するたびに実行するアクションを指定することができます。 アクションは、 入出力、サブプログラムのコール、および外部ベクトルと変数の変更を行う C 言語ステートメントです。

アクションは値を戻し、以前のアクションで戻された値を取得します。 字句解析プログラムは、トークンの値を戻すこともできます。

アクションを指定するときは、文法ファイルの中に 1 つ以上のステートメントを {} (中括弧) で囲んで書き込みます。 次の例は、アクションに関する文法規則です。
A  :  '('B')'
   {
     hello(1, "abc" );
   }
および
XXX  :  YYY  ZZZ
     {
     printf("a message¥n");
     flag = 25;
     }

アクション間の値の受け渡し

他のアクションで生成された値を手に入れる場合、アクションは、 ドル記号から始まる yacc パラメーター・キーワード ( $1$2、...) を使用することができます。 これらのキーワードは、規則の右側のコンポーネントによって戻された値を、 左から右に読んで参照します。 例えば、次の規則があるとします。
A  :  B  C  D  ;

この場合、$1 には B を認識したルールによって戻された値が入ります。 $2 には C を認識したルールによって戻された値、$3 には D を認識したルールによって戻された値が入ります。

値を戻す場合、 アクションは疑似変数 $$ を何らかの値に設定します。 例えば、次のアクションは値 1 を戻します。

{ $$ = 1;}
デフォルトでは、規則の値はその中の最初のエレメント ($1) の値です。 したがって、次のような形式の規則にはアクションを提供する必要はありません。
A : B ;

次の $ (ドル記号) で始まる追加 yacc パラメーター・キーワードを使用すると、タイプの検査も可能です。

  • $<Tag>$
  • $<Tag>Number

$<Tag>Number は、<Tag> で参照される共用体メンバーのタイプを参照させます。 これは、.tag を参照に追加して、Tag によって識別される共用体メンバーをアクセスするようにします。 この構造は、$$.Tag または $1.Tag を指定するのと同じです。 %type 宣言によって戻りタイプを指定できない規則の中でアクションを使用するときに、 この構造を使用することができます。 %type が非終端名に対して宣言されている場合は、<Tag> 構成を使用しません。共用体は自動的に参照されます。

規則の中でのアクションの書き込み

規則が完了する前に構文解析プロセスの制御を取得するためには、 規則の中でアクションを書き込みます。 この規則が $ キーワードを使用して値を戻すと、 この規則の後に続くアクションでその値を使用することができます。 この規則は、その前にあるアクションの戻した値を使用することもできます。 したがって、次の規則は、x1 に設定し、yC が戻した値に設定します。 規則 A の値は、デフォルトの規則に従って B が戻した値です。

A  :  B
        {
           $$ =1;
        }
        C
   {
        x = $2;
        y = $3;
   }
   ;
内部では、yacc コマンドが、 途中で起こるアクションの新しい非終端記号名を作成します。 また、この名前を空文字列に対して突き合わせる新しい規則も作成します。 したがって、yacc コマンドは、 前述のプログラムを次の形式で作成されたかのように扱います。
$ACT  :  /* empty */
      {
         $$ = 1;
      }
      ;
A     :  B  $ACT  C
      {
         x = $2;
         y = $3;
      }
      ;

ここで、$ACT は空のアクションです。