
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