
On 06/06/2004 11:12 AM, Eric Niebler wrote: [snip]
In addition, I have solved the cyclic/dangling reference problem. A regex can refer to other regexes or itself and it tracks changes to its referenced regexes. It lets you copy regex objects freely, even putting them in containers, and they keep their references alive. It works with nothing more sophisticated than shared_ptr and weak_ptr -- no garbage collection is necessary. No cycles are created ever, so no cycles need to be collected.
There are only two questions: (1) is the rule-as-pointer metaphor acceptable? and (2) can we find a palatable syntax?
The syntax issue is this: if we take assign to be shallow (creating aliases) we need a different syntax for deep assign. I am using *= to mean deep-assign. Perhaps there is a better solution.
The grammar_pipeline/{base,eff}/productions avoids the cycle problem by just using indexes into a vector of "grammar expressions". IOW, a non-terminal expression is create with nt_exp(unsigned nt_id), where nt_id is an index into a vector of sole_ptr smart pointers to the grammar expression defining the rhs of the non-terminal. You might think this would lead to a "semi-dangling pointer" (a nt_exp whose index points to a deleted vector of sole_ptr's); however, deletion of the sole_ptr's delete's the rhs. Hence, the only way to create such a semi-dangling pointer would be to create a nt_exp somewhere other than on the rhs of a non-terminal. There's that danger; however, I don't know that it's that significant. If one want's to do that, he/she must clone the rhs. Anyway, I may discover this won't work in the future, but right now it looks OK to me.