2

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?

DaJunkie
  • 556
  • 1
  • 5
  • 15

1 Answers1

2

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"?

Community
  • 1
  • 1
sehe
  • 374,641
  • 47
  • 450
  • 633
  • Thanks for your answer, @sehe. I solved it like this: `lit("{") [phx::bind(&RtfState::saveState, ref(state))]`, `lit("}") [phx::bind(&RtfState::restoreState, ref(state))]` and `rtfFontTable [phx::bind(&RtfState::addFonts, ref(state), _1)]` – DaJunkie Jun 08 '15 at 12:12