Search code examples
c++grammarboost-spiritboost-spirit-qi

boost::spirit::qi - Working with instance members in grammar struct


I am trying to create a grammar for parsing RTF files. At some points I need to store some information in the scope of the grammar. I know, that I could use inherited attributes, but this would worsen readability.

So I asked myself if instance member variables of the grammar could solve my problem and, if yes, how should I use them in my grammar?

For example, I need to keep track of the active codepage for character conversion. Is it good practice to have an int codepage inside my grammar struct?

What I further want is, to call some function for putting and popping the state variables on a stack. I think I will combine the state information in a RtfState class, which I can extend as needed. What would be the best way to call member functions of the grammar struct?


Solution

  • You can. Just use semantic actions with phx::bind:

    namespace phx = boost::phoenix;
    switch_cp = qi::int_ [ phx::bind(&MyGrammar::_codepage, this) = _1 ];
    

    However, keep in mind that ruins reentrancy: don't use it if the related rules can be nested.


    Alternatively, calling methods would look like: e.g.

    switch_cp = qi::int_ [ phx::bind(&MyGrammar::push_codepage, this, _1) ];
    
    reset_cp = qi::eps [ phx::bind(&MyGrammar::pop_codepage, this) ]
    

    General reading: Boost Spirit: "Semantic actions are evil"?