bjam_win その16 クロージャの初期値
bjam_grammarのwhile、ルールの名前付き引数、ローカル変数/ルールを実装しました。
bjam_grammar.hppの差分
これでBoost.SerializationやBoost.Statechart等の複雑なJamfileでもターゲットのリストを取得できるようになりました。
今日気が付いたことは、クロージャ変数の初期化に関してです。
Boost.Spiritのドキュメントを読んだときは「ふ〜ん」としか思わなかったのですが、これは実質ルールに対する引数に相当するんですね。
最新のドキュメントにはないのですが、古いドキュメントには次の記述がありました。
最も重要なことに、クロージャ変数は EBNF 文法仕様からアクセス可能であり、またパーサ情報を上流や下流に、最上位ルールから終端記号へとトップダウンの再帰下降で渡すために使うことが出来る。一つには、クロージャは継承属性や合成属性を持つことのできるパーサを提供する。これらはほぼ戻り値と関数引数に類似したものである。
Closures
bjam_grammarではこれをルールの定義がグローバルかローカルかを指定するのに使うことにしました。
ルール"rule_"は第一メンバにこのフラグを持っていて、
struct rule_closure : boost::spirit::closure< rule_closure , bool , std::string , std::vector<std::vector<std::string> > > { member1 local; member2 rulename; member3 fields; }; boost::spirit::rule< ScannerT, typename rule_closure::context_t> rule_;
次のように使い分けています。
local = "local" >> space >> ( rule_(true) // ローカルルール | local_assign ) ; statement = ( actions | rule_(false) // グローバルルール ...
すでに書いたルールも、これを使えばより簡潔に記述できそうです。