这很自然。您正在解析 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); }
依此类推(那里可能有一个错误,不记得 $s 是从 0 还是从 1 开始的)。您需要自己实现该copy
函数来管理内存分配,bison 只会为值提供一个堆栈。最后你会得到一棵树(我相信通常被称为语法树),你可以运行它,对于类型为 IF_STMT 的节点,评估 if_stmt.expr,如果它返回 true,则评估 if_stmt.stmt,等等。
然后,当您完成语言解析后,您可以“执行”您的字节码,当您点击 if 语句时,评估表达式,如果为真(不是),执行上述语句,然后当你点击一个打印指令(你不会因为表达式是假的),你打印你的'hi',你就会得到你正在寻找的结果(也就是说,什么都没有打印出来)。
这就是你需要做的事情。在使用野牛解析时,您不能(轻松地)进行条件执行。