次: , 前: Multiple Types, 上: Semantics


3.5.3 アクション

文法規則にともなうアクションは、その規則が認識されるたびに実行される Cのプログラムからなります。 アクションの仕事のほとんどは、関連するトークンまたは小さいグループから 規則にしたがって構成されるグループの、意味値の計算です。

アクションは、Cの複文のように、ブレースで囲まれたCの文からなります。 アクションは、規則のどの場所にも置け、その場所で実行されます。 規則のほとんどは、規則の終わりの構成要素の並びの後に、 1つだけアクションを持ちます。 規則の途中に置かれたアクションは、手の込んだ方法で特別な目的に使われます (see Actions in Mid-Rule)。

アクションの中のCで書かれたプログラムは、 規則の第n番目の要素に対応する意味値を、 $nという書式で参照できます。 また、その規則が構成するグループの意味値を、 $$という書式で参照できます。 アクションが構文解析器ファイルに複写されるときに、Bisonは、 上記の構成要素を配列要素への参照に変換します。

例を示します。

     exp:    ...
             | exp '+' exp
                 { $$ = $1 + $3; }

この規則は、加算記号で結び付けられた2つの小さいexpグループから、 1つのexpを構成します。 このアクションの中で、$1$3は、 規則の右側の最初と3番目の記号であるexpグループの 意味値を参照します。 この規則によって認識される加算式の値になるように、 和が$$に代入されます。 もし、`+'トークンに有用な値があるならば、 それを$2として参照できるでしょう。

規則に対してアクションを指定しなければ、Bisonは、 省略時アクション$$ = $1を補います。 したがって、規則の最初の記号の値が規則全体の値になります。 もちろん、両者の型が一致する場合にのみ、省略時アクションは有効です。 空規則に対する省略時アクションは無意味です。 すべての空規則は、その規則の値が必要ならば、 明示的なアクションを持つ必要があります。

$nnは0または負が許され、 現在の規則にマッチする前にスタックに積まれていた トークンとグループの意味値を参照します。 これは非常に危険な手法で、安全に使うためには、 その規則が適用される文脈をあなたが完全に理解している必要があります。 これを安全に使える例を示します。

     foo:      expr bar '+' expr  { ... }
             | expr bar '-' expr  { ... }
             ;
     
     bar:      /* 空 */
             { previous_expr = $0; }
             ;

barがここに書かれた方法でのみ使われるならば、 fooの定義の中でbarより前の exprの値を$0が参照します。