From: Joel de Guzman (joel_at_[hidden])
Date: 2004-05-27 03:03:16
Eric Niebler wrote:
> Joel de Guzman wrote:
>> rule<> a = x;
>> rule<> a;
>> a = x;
>> How should this behave if x is an int_p?
> The int_p gets stored in an object on the heap, and the rule<> stores a
> shared_ptr to a polymorphic base.
>> Now how should it behave if
>> x is another rule? Consider a concrete example (snipped from the pascal
>> rule<> identifier;
>> rule<> fileIdentifier;
>> identifier = ....
>> fileIdentifier = identifier; // an alias
> The shared_ptr's reference count goes up. What's the problem?
Ha ;-) Been there, done that. That was how Spirit behaved in
v1.5 (a failed experiment). This dual behavior confused people.
Simply, "=" in Spirit should not be confused with assignment.
This behavior in fact killed the pascal grammar. Consider this:
a = b; // alias. a shares b
// (points to nothing_p since b is still undefined)
b = int_p; // now b is an int_p
// at this point, a still refers a points to nothing_p
// and did not (cannot) follow b's change.
Also, be wary of cycles. It is quite common that a rule references
another rule which indirectly references the start rule, in a cycle.
No, share_ptr can't handle this common situation. This scheme (using
shared_ptr) can't handle forward declared rules like the humble
group = '(' >> expression >> ')';
factor = integer | group;
term = factor >> *(('*' >> factor) | ('/' >> factor));
expression = term >> *(('+' >> term) | ('-' >> term));
Note that group is defined *before* expresion is defined. Note
too that this is cyclic. expression indirectly references group,
while group references expression.
There's only one solution: use plain references. When a rule
is referenced in the RHS of another rule, it is held by reference.
Ah, yes, another solution: use garbage collection. Ehm... no thanks ;-)
-- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk