
Eric Niebler wrote:
My point was that rule<> doesn't "do as the ints do", which can be surprising to some.
well, rule(s) do as the refs do :-), to be precise. They aren't values, they are references.
I would love for this to work:
rule<> a;
{ rule <> b;
// match balanced, nested parens. // b refers to itself by reference // (Note: ! means optional, no special syntax // required to get by-ref semantics here) b = '(' >> !b >> ')';
// a assumes b's behavior a = b; }
// a still has b's behavior. // this matches balanced, nested parens parse( "(())", a );
Currently, this crashes because 'a' holds 'b' by reference and tries to access it after 'b' has gone out of scope and been destroyed. I haven't yet thought of a way to make this work, but I'm not convinced it's impossible.
I now agree that rules should have by-ref semantics when embedded in another rule. But in simple assignment statements ("a=b;"), it would be nice if rules behaved as the ints do. I'm sure this will draw fire from the EBNF purists who want rule assignment to have by-ref semantics, but IMO C++ types that don't have normal copy and assignment semantics are just hard to work with.
What you outlined here is actually the semantics of the stored_rule that I mentioned a few posts ago: http://www.boost.org/libs/spirit/doc/stored_rule.html If one wants this semantics, she can have it. Actually, stored_rule can also do what you suggested in a previous post (regarding the &r or ref(r). The difference is that by default, stored_rule(s) are held by reference, unless otherwise notified to do a "copy": start = *(a | b | c); is equivalent to: stored_rule<> start; start = a; start = start.copy() | b; start = start.copy() | c; start = *(start.copy()); and, yes, stored_rule(s) use shared_ptr. So, again, be wary of cycles. I was so eager when Lary Evans hinted at a shared_ptr implementatiion with GC. I'm still so eager! Cheers, -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net