それは当然です。print ステートメントを解析しているので、「cout」が実行されます。あなたがしようとしているのは、印刷命令を格納するバイトコードのようなものを作成することです。次に、この出力命令を if 式と組み合わせて、if ステートメント命令を作成できます。
頭のてっぺんから、Bison の正確なステートメントを思い出すことはできません (ドキュメントを調べる必要があります) が、通常、値スタックの型、通常は構造体の結合を定義する必要があります。 this (ただし、値スタックのタイプにする bison コマンドがあります)。
union {
int type;
struct {
int type; // must always be first, this is a union
union stmt *stmt; // conditional stmt to execute
union expr *expr; // expression to evaluate
} if_stmt;
struct {
int type;
} print_stmt;
} stmt;
これにより、次のようなルールを文法に入れることができます
stmt: IF '(' expr ')' stmt { $$.type = IF_STMT; $$.if_stmt.expr = copy ($3); $$.if_stmt.stmt = copy ($5); }
など(そこにoff-by-oneエラーがある可能性があり、$sが0または1で始まるかどうか思い出せません)。copy
メモリ割り当てを管理するには、関数を自分で実装する必要があります。bison は値のスタックのみを提供します。最後に、ツリー (一般に構文ツリーと呼ばれていると思います) が作成されます。このツリーを実行して、IF_STMT タイプのノードについて if_stmt.expr を評価し、true が返された場合は if_stmt.stmt を評価します。等々。
次に、言語の解析が終了したら、バイト コードを「実行」できます。if ステートメントにヒットすると、式を評価し、true (そうではない) の場合、上記で概説したようにステートメントを実行します。 print-instruction を実行すると (式が false であるため、実行されません)、'hi' が出力され、探している結果が得られます (つまり、何も出力されません)。
それはあなたがそれについて行く必要がある方法です。バイソンで解析中に条件付き実行を (簡単に) 行うことはできません。