I had the same problem when implementing an SQL parser in qi. I had separate grammars for statements, fields, tables, etc, but fields and tables, for instance, could be statements too sometimes (subqueries). In my case, I solved the problem like this:
The top grammar (the one that you always start parsing with) held shared pointers to all sub grammars. The constructor of the top grammar would create instances of all sub grammars and pass them instances of each other as weak pointers. That way there is only one instance of each grammar created. There are no circular shared_ptr
thanks to weak_ptr
. So basically, the top grammar owns all sub grammars and just passes pointers around to each other.
So in your case, I would create a TopGrammar
class, have it own FooGrammar
and BarGrammar
. Once they're constructed, pass them pointers to each other. And in TopGrammar
's start rule just invoke FooGrammar
.
Since TopGrammar
owns all subgrammars, you're sure that their lifespan is sufficient.