Boost logo

Boost :

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

     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

Boost list run by bdawes at, gregod at, cpdaniel at, john at