bison生成的规则文件的覆盖范围



我有一个非常大的bison规则文件,想知道是否有一种简单的方法可以从后面的程序中获得这些规则的覆盖范围。

我用bison生成了一个解析器。对不同的文件运行解析器,并希望查看.yy文件中的哪些行被触摸。

据我所知,没有正式的方法来生成这样的报告。但如果你愿意深入野牛的内部,这是可能的。

请注意,您只能为解析器语义操作生成覆盖率报告。";解析器规则";;规则被编译成一个状态机,状态与规则之间的对应关系是多对多的。但这会告诉你每个规则完成了多少次,这可能是你想知道的。

还要注意,解析器不区分规则最终语义动作和中间规则动作,因为中间规则动作实际上被编译为生成的非终端的减少动作。

这篇文章的其余部分是非官方的,不应该被用来处理所有未来版本的Bison。它也不会与其他野牛骨骼一起工作(尽管它可能会被改编(;我是根据当前版本3.8.2编写的。

挂接解析器的最简单方法是劫持宏YY_REDUCE_PRINT,跟踪工具使用它来跟踪减少操作。因此,每次减少时都会执行它。即使跟踪没有编译到解析器中,也会发生这种情况;在这种情况下,宏被定义为no-op。不过,YY_REDUCE_PRINT不是接口的官方部分,因此其名称和功能可能会在没有通知的情况下发生更改。此外,它还不能正式用于自定义,生成的源代码也不会尝试检查它是否是以前定义的。所以你必须等到它在解析器模板中定义好,然后重新定义它。当然,重新定义它会使它不可用于跟踪日志,所以这与调试跟踪不兼容。事实证明,½initial-action代码块是在YY_REDUCE_PRINT的定义之后注入的,所以这就是我进行重新定义的地方。这也不能保证。

我使用lalr1.cc骨架,用最近的几个bison版本(3.7.1和3.8.2(非常轻松地测试了以下代码。这似乎有效,但你的里程数可能会有所不同。

代码非常简单。首先,重新定义YY_REDUCE_PRINT,它将进入您的.yy文件。您可能希望以某个配置宏为条件,以保留生成调试跟踪的可能性。重新定义的YY_REDUCE_PRINT宏所做的只是向覆盖直方图添加一个。(这里,根据Calc++示例,drv是解析器驱动程序的一个实例(:

%initial-action {
#undef YY_REDUCE_PRINT
#define YY_REDUCE_PRINT(Rule) drv.register_rule(Rule)
}

直方图本身需要实现;它可以进入driver.hhdriver.cc:

标题:

// Register execution of a semantic action.
void register_rule(int rule);
// Count of executions of each rule.
std::vector<unsigned> rule_count;

实施:

void
driver::register_rule(int ruleno) {
if (ruleno > 0) {
if (ruleno > rule_count.size()) rule_count.resize(ruleno);
++rule_count[ruleno - 1];
} 
}

规则编号与生成的报告文件中的编号相对应。规则0(接受规则(将不被计算在内。

最新更新