boost::spirit 和 RAII 中的 scope 对象

scope objects in boost::spirit and RAII

提问人:Frank Puck 提问时间:6/30/2023 更新时间:7/1/2023 访问量:19

问:

在某些语言中,可以再次打开和关闭新作用域。在 C++ 中,这将是大括号。 假设在遇到左大括号时创建一个新范围,并在遇到匹配的右大括号时关闭它。 如果在遇到右大括号之前出现解析错误,会发生什么情况?如何确定由开口大括号打开的示波器是否被正确丢弃?

助推精神 raii

评论

0赞 sehe 6/30/2023
这和灵有什么关系呢?它似乎更适合 programming.se,而且它实际上只与解析有切线关系 - 无论您使用什么工具来帮助生成解析器代码。
0赞 Frank Puck 6/30/2023
@sehe 这是一个提振精神的问题。是否可以简单地认为,当不再需要它时,例如,当规则成功完成或错误时,由左大括号的语义操作创建的对象是属性销毁的?
0赞 sehe 6/30/2023
好的,我已经回答了这个简化的问题。我仍然坚持认为,在解析过程中根本不会出现示波器的语义。将解析与解释(甚至执行)混为一谈的唯一原因是,如果您需要在收到脚本之前执行脚本。虽然可能,但它确实引发了许多与安全性和原子性或更新相关的危险信号。我希望我的脚本在末尾包含语法错误时无法运行,而不是部分执行,使我的数据处于损坏状态。

答:

1赞 sehe 6/30/2023 #1

@sehe 这是一个提振精神的问题。是否可以简单地认为,当不再需要它时,例如,当规则成功完成或错误时,由左大括号的语义操作创建的对象是属性销毁的?

不然它能如何工作?对象生存期的确定性销毁是语言的一个属性。所以,除非你愿意假设 Qi 是有意为之泄露内存,否则你就可以开始了。


当然,如果你坚持,你可以强行创建内存泄漏,例如,但你可以在没有 Spirit 的情况下做同样的事情(只需使用内存泄漏运算符,)。eps[px::new_<int>(42)]operator* new

现在,这尤其/仅当您想在 AST 类型中使用动态多态性时才会发挥作用:

正如我之前所说

您正在使用语义操作。通常,这已经错过了嵌入式语法的最佳位置,这就是为什么我将 126 135 个答案链接到 Boost Spirit:“语义行为是邪恶的”?

让这 136 :)

有一次,我修复了使用指针属性的语法中的泄漏: 在 Spirit:Qi 中构建自定义表达式树(没有 Utree 或 Boost::Variant)

0赞 moaz ahmad 7/1/2023 #2

如果在匹配的右大括号之前发生解析错误,则将其视为无效范围。在这种情况下,编译器会将其报告为解析错误:

  1. 您应该检查代码中的分号是否缺少分号。

  2. 您可以重构代码以避免解析错误。

  3. 有一些在线工具,如 onlinegdb,可以通过美化您的代码来在一定程度上解决这些问题。