boost::spiritにおけるparse用データの切り離し

構文解析では解析の途中結果を置いておくスタック等をグローバルに持っておくのが普通だが,
漏れはそれが嫌なのでそれらのparseに必要な情報をクラスにカプセル化することにした.
でspiritではsemantic actionを,関数ポインタあるいはfunctorを通じてcall backさせることにより実現しているが,
クラスのメンバ関数はspiritのcall backにできないことに気が付く.
(クラスメンバ関数のポインタ渡してもmessageをdispatchするオブジェクトを指定できない)
なので,しばらく考えた結果pimplイディオム(個人的にはピンプル♪と呼んでいるw)をグローバルなfunctorに適用する方法を思いつく.

#include 
#include 

using namespace std;
using namespace boost::spirit;

class SemanticAction
{
public:
  void doAction{cout << "do action" << endl;}
};

class OnTrigger
{
public:
  OnTrigger(SemanticAction & action) : r_impl(action){}

  template
  void operator()(IteratorT first, IteratorT last) const
  {
    r_impl.doAction();
  }

private:
  SemanticAction & r_impl;
};

class MyGrammar : public grammar
{
public:
  MyGrammar(SemanticAction & action) : act(action), onTrigger(action){}

  template
  struct definition
  {
    rule r;

    definition(MyGrammar const& self)
    {
      r = (*anychar_p)[self.onTrigger];
    }

    rule const& start() const
    {
      return r;
    }
  };

private:
  SemanticAction & act;
  OnTrigger onTrigger;
};

int main(int argc, char *argv[])
{
  SemanticAction act;
  MyGrammar g(act);
  parse_info<> info;

  info = parse("abc", g);

  return 0;
}

definitionのコンストラクタの引数のselfってこういうときのためのものだったのねん.
あ,ピンプル♪じゃなくてリンプル♪じゃねーか!なんてツッコミはなしの方向でw