c – boost :: spirit的规则的复制或引用语义?
我试图在Boost.Spirit中编写一个
shell语言解析器.但是,我不清楚关于规则语义的一些基本问题.
看文档,有成员r.alias()和r.copy()的规则.国际红十字会,这些成员应分别返回规则的引用和规则内容的副本.但是,当我在另一个规则的定义中使用规则时,没有明确规定会发生什么.从我的实验,我发现相互递归的规则可以定义为: rule<Iter> r1,r2; r1 = ... >> r2 >> ...; r2 = ... >> r1 >> ...; 这表明规则在解析器表达式中被引用.问题是,当变量超出范围时,它会做什么,例如: rule<Iter> r1; { rule<Iter> r2; r1 = ... >> r2 >> ...; r2 = ... >> r1 >> ...; } ... // use r1 在同一个注释中,将从包含类型规则工作(r.copy())的值的解析表达式分配给一个规则也将是类型规则的值,不是吗?例如. rule<Iter> f() { return char_('a') << char_('b'); } rule<Iter> r1 = ... << f(); 任何人都可以启发我关于规则副本和引用的详细语义,并可能纠正这个帖子中的任何误解? 解决方法
答案取决于你所指的圣灵版本.
Spirit.Classic(前Spirit V1.x)实现规则的特殊复制语义.文件说:
赋值运算符基本上引用了rhs规则,而不创建深层副本.这样做是为了允许: rule<> r1,r2; r1 = ...; r2 = r1; 但事实证明是高度的混乱,因为它阻止了与“正常”对象相同的处理规则. 因此,有一个成员函数rule :: copy(),允许做一个规则的明确的深层拷贝(例如将它们存储在STL容器中). 同时这个: r2 = r1.copy(); 是纯粹的错误r2将引用从函数copy()返回的r1的(被破坏的)临时副本. 在Spirit.Qi(即Spirit V2.x)中,行为被部分改变.规则现在在解析器之外处理时按预期的方式运行.您可以将它们正常存储在容器中(赋值操作符暴露预期的行为).但是要注意的是,解析器内部的表达式规则仍然被引用保留,这仍然允许以与之前相同的方式引用规则: rule<> r1,r2; r1 = ... >> r2 >> ...; r2 = ... >> r1 >> ...; 有时有必要制作一个规则的深层副本,所以还有成员函数副本. 更改的副本语义有另一个副作用.构造如: r1 = r2; 现在正在创建一个(深)的r2副本,这可能不是你期望的,特别是如果r2只有在被分配到r1之后才能分配它的rhs.由于这个原因,有一个新的成员函数别名启用此角色的参考语义: r1 = r2.alias(); 无论如何,在两个版本的Spirit中,如果从解析器表达式引用的规则的一部分超出范围,您将最终得到悬挂引用. BTW,Spirit版本都不实现函数rule :: ref(). (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |