nocalc

Boost.Spiritの利用例としてBoost.Waveのソースを少し読みました。(Waveの存在自体を忘れていました。)
Boost.Spiritのサンプルでは単純すぎる場合が多いので、いろいろと参考になります。


Boost.Waveでもパースと値の評価を同時進行で行っているようで、「短絡評価の実装」と似たルールlogical_and_expが見つかりました。

logical_and_exp
    =   inclusive_or_exp[logical_and_exp.val = arg1]
        >> *(   if_p(impl::as_bool(logical_and_exp.val))
                [
                    pattern_p(T_ANDAND, MainTokenMask)
                    >>  inclusive_or_exp
                        [
                            logical_and_exp.val = 
                                impl::binary_and(logical_and_exp.val, arg1)
                        ]
                ]
                .else_p
                [
                    // if one of the && operators is false, no more
                    // evaluation is required
                    pattern_p(T_ANDAND, MainTokenMask)
                    >>  inclusive_or_exp_nocalc
                        [
                            logical_and_exp.val =
                                impl::to_bool(logical_and_exp.val)
                        ]
                ]
            )
    ;
boost/wave/grammars/cpp_expression_grammar.hpp

bjam_grammarではno_actions_dディレクティブで動作を切り替えていましたが、logical_and_expでは値の評価が必要な場合はinclusive_or_exp、必要ないときはinclusive_or_exp_nocalcを呼んでいます。
inclusive_or_expとinclusive_or_exp_nocalcの違いは、値評価用のセマンティックアクションがあるかどうかだけで、文法としては同じものです。
文法が再帰的に定義されるため、expression_grammarで使われるルールのほとんどは無印版とnocalc版があります。


同じ文法を重複して持ちたくなくてno_actions_dを使っていましたが、Boost.Waveがやってるなら二重持ちでもいいかなぁと思えてきました。