$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
From: Joel de Guzman (joel_at_[hidden])
Date: 2004-05-27 03:03:16
Eric Niebler wrote:
> Joel de Guzman wrote:
> 
>>
>> Consider:
>>
>>     rule<> a = x;
>>
>> or:
>>
>>     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
>> parser):
>>
>>     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:
     rule<> a;
     rule<> b;
     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
calculator:
     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 ;-)
Cheers,
-- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net