复制或引用语义boost :: spirit的规则<>? [英] Copy or reference semantics of boost::spirit's rule<>?

查看:147
本文介绍了复制或引用语义boost :: spirit的规则<>?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在Boost.Spirit中编写一个shell语言解析器。但是,我不清楚关于规则的语义的一些基本问题。

I am trying to write a shell language parser in Boost.Spirit. However, I am unclear about some basic issues regarding semantics of rules.

查看文档, r.alias() r.copy() $ c>。 IIUC,这些成员应分别返回对规则的引用和规则内容的副本。但是,没有明确指定当我在另一个规则的定义中使用规则时会发生什么。从我的实验,我发现相互递归的规则可以定义:

Looking at the documentation, there are members r.alias() and r.copy() of rule. IIUC, these members should return a reference to the rule and a copy of the rule's contents, respectively. However, it is not clearly specified what happens when I just use the rule in a definition of another rule. From my experiments, I found mutually recursive rules can be defined by:

rule<Iter> r1, r2;
r1 = ... >> r2 >> ...;
r2 = ... >> r1 >> ...;

这表明规则是通过引用在解析器表达式中。问题是,当变量超出范围时,它做什么,例如:

which suggests the rules are taken by reference inside parser expressions. The problem is, what does it do when the variable goes out of scope, eg:

rule<Iter> r1;
{ 
  rule<Iter> r2;
  r1 = ... >> r2 >> ...;
  r2 = ... >> r1 >> ...;
}
... // use r1

从包含类型规则工作( r.copy()的右值的解析表达式分配规则将是类型 rule 太,不是)?例如

On the same note, would assigning to a rule from a parsing expression containing a rvalue of type rule work (r.copy() would be a rvalue of type rule too, isn't it)? eg.

rule<Iter> f() { return char_('a') << char_('b'); }
rule<Iter> r1 = ... << f();

任何人都可以启发规则的详细语义

Can anybody enlighten me on the detailed semantics of rule's copies and references, and possibly correct any misconceptions in this post?

推荐答案

答案取决于什么版本的Spirit你指的是。

The answer depends on what version of Spirit you're referring to.

Spirit.Classic(前Spirit V1.x)为规则实现特殊复制语义。文档说:

Spirit.Classic (the former Spirit V1.x) implements special copy semantics for rules. The documentation says:


当在
中的任何地方引用规则时,EBNF
表达式的右侧,该规则由
表达式通过引用来保持。客户端的
责任确保
引用的规则保留在
范围内,并且在被引用时不会被破坏

When a rule is referenced anywhere in the right hand side of an EBNF expression, the rule is held by the expression by reference. It is the responsibility of the client to ensure that the referenced rule stays in scope and does not get destructed while it is being referenced.

赋值运算符基本上引用rhs规则,而不创建深度副本。这是为了允许:

The assignment operator essentially references the rhs rule without creating a deep copy as well. This was done to allow:

rule<> r1, r2;
r1 = ...;
r2 = r1;

但是结果是很高的混乱,因为它阻止处理规则与正常对象。

But this turned out to be highly confusion as it prevented handling rules the same way as 'normal' objects.

因为这个原因,有成员函数 rule :: copy()的规则(例如将它们存储在STL容器中)。

For that reason there was the member function rule::copy(), allowing to make explicit deep copies of a rule (for instance to store them in an STL container).

同时:

r2 = r1.copy();

是无效的。 r2 将引用从函数 copy($)返回的 r1

is plain wrong. r2 would refer to the (destructed) temporary copy of r1 returned from the function copy().

在Spirit.Qi(即Spirit V2.x)中,改变。规则在解析器外处理时现在表现正常。您可以将它们正常存储在容器中(赋值运算符暴露预期的行为)。但请注意,解析器表达式规则仍然通过引用来保存,这仍然允许以与之前相同的方式引用规则:

In Spirit.Qi (i.e. Spirit V2.x) the behaviour is partially changed. rules are now behaving as expected when handled outside of parsers. You can store them normally in containers (the assignment operator exposes the expected behavior). But beware, that inside a parser expression rules are still held by reference, which still allows to refer to a rule the same way as before:

rule<> r1, r2;
r1 = ... >> r2 >> ...;
r2 = ... >> r1 >> ...;

有时需要制作规则的深度副本,所以仍然有成员functon copy

Sometimes it's necessary to make a deep copy of a rule, so there is still the member functon copy.

更改的副本语义有另一个副作用。构造如:

The changed copy semantics have another side effect. Constructs like:

r1 = r2;

现在创建 r2 ,这可能不是你期望的,特别是如果 r2 将得到其rhs分配只有在被分配到 r1 。因此,对于这种情况,有一个新的成员函数 alias 启用引用语义:

are now creating a (deep) copy of r2, which might not be what you expect, especially if r2 will get its rhs assigned only after being 'assigned' to r1. For that reason there is the new member function alias enabling reference semantics for this corner case:

r1 = r2.alias();

无论如何,在Spirit的两个版本中,如果部分规则参考从解析器表达式超出范围。

In any case, in both versions of Spirit you will end up with dangling references if part of the rules referenced from a parser expression go out of scope.

BTW,Spirit版本实现一个函数 rule :: ref()

BTW, neither Spirit version implements a function rule::ref().

这篇关于复制或引用语义boost :: spirit的规则&lt;&gt;?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆