
A few years ago, I asked how to define a grammar with Proto to match something like this: if_(expr) [ stmt, stmt, ... ].else [ stmt, stmt, ... ]; The answer was to do this: struct Grammar; struct ExpressionGrammar; struct StatementGrammar; struct Domain; template<typename Expr> struct Expression : proto::extends<Expr, Expression<Expr>, Domain> { typedef proto::extends<Expr, Expression<Expr>, Domain> base_type; Expression(Expr const & expr = Expr()) : base_type( expr ) {} }; struct Domain : proto::domain< proto::generator< Expression >, Grammar> {}; struct If {}; BOOST_PROTO_DEFINE_FUNCTION_TEMPLATE( 1 , if_ , Domain , (If) , BOOST_PP_SEQ_NIL ); // Here is the grammar for if_ statements // matches if_(e1)[e2] struct IfGrammar : boost::proto::subscript< boost::proto::arg< boost::proto::unary_expr< If, ExpressionGrammar >, >, StatementGrammar > {}; // An else_ "operator" template<typename Expr> struct Expression< Expr , typename enable_if<proto::matches<Expr, IfGrammar> >::type > : proto::extends<Expr, Expression<Expr>, Domain> { Expression() : else_(proto::make_expr<Else>(*this)) {}; proto::result_of::make_expr< Else, // else is now an "operator" Expression<Expr> const >::type const else_; }; // matches if_(e1)[e2].else_[e3] struct IfElseGrammar : boost:proto::subscript< boost::proto::arg< boost::proto::unary_expr< Else, IfGrammar >, >, StatementGrammar > {}; I didn't understand it then and I don't now. :) However, it seems to be obsolete since BOOST_PROTO_DEFINE_FUNCTION_TEMPLATE doesn't seem to exist anymore (it's not documented, anyway). So how would this be formulated in modern Boost.Proto? I'm guessing I will need an expression template wrapper (called Expression<> above) that uses some combination of BOOST_PROTO_BASIC_EXTENDS, BOOST_PROTO_EXTENDS_SUBSCRIPT and BOOST_PROTO_EXTENDS_FUNCTION. But of course not all statements have a valid operator() overload and no expressions do. I guess the grammar will take care of that, yes? I'm really puzzled about how to do the ".else_" part. I was hoping I could look to Phoenix to get a clue but it doesn't seem to use Proto. Any help? Thanks! -Dave