Search code examples
c++boostboost-spirit

Dynamically switch parser while parsing


I'm parsing spice netlists, for which I already have a parser. Since I actually use spectre (cadence, integrated electronics), I want to support both simulator languages (they differ, unfortunately). I could use a switch (e.g. commandline) and use the correct parser from start. However, spectre allows simulator lang=spectre statements, which I would also want to support (and vice versa, of course). How can this be done with boost::spirit?

My grammar looks roughly like this:

line = component_parser             | 
       command_parser               |  
       comment_parser               | 
       subcircuit_parser            | 
       subcircuit_instance_parser;

main = -line % qi::eol >> qi::eoi;

This toplevel structure is fine for both languages, so i need to change the subparsers. A first idea for me would be to have the toplevel parser hold instances (or objects) to the respective parser and to switch on finding the simulator lang statement (with a semantic action). Is this a good approach? If not, how else would one do this?


Solution

  • You can use qi::lazy (https://www.boost.org/doc/libs/1_68_0/libs/spirit/doc/html/spirit/qi/reference/auxiliary/lazy.html).

    There's an idiomatic pattern related to that, known as The Nabialek Trick.

    I have several answers up on this site that show these various techniques.