
dan marsden wrote:
Hi
Does proto support member access in its tree generation in any way. I'm looking at a few of the phoenix statement forms, particularly:
if_(pred)[statements].else_[statements]
and
try_[statements].catch_<exception_type>()[statements].catch_call[statements]
I need to specify member access to else_ and catch_<exception_type> etc. Is this something I'll have to hand roll, or does proto have some extension mechanism I've missed that will let me add these to the expression tree generation process?
Yes, proto::extends is the extension mechanism.
As phoenix expressions have operator(), I'm already using an expression wrapper around all my proto expressions, so I presume that is where I would add any special member support?
Yep. You could be to put all such members into the Phoenix expression wrapper and use a grammar to flag or disallow invalid uses. The members would just be Proto terminals, like "terminal<phoenix::tag::else_>::type const else_". A better approach might be to partially specialize your wrapper such that members like else_ only show up where they make sense. So, something like: template<typename Expr, typename EnableIf = void> struct phoenix_expr : proto::extends<Expr, phoenix_expr, phoenix_domain> { // default phoenix stuff here, including // operator() }; // Here is the grammar for if_ expressions struct IfGrammar : proto::subscript< proto::terminal<phoenix::tag::if_> proto::_ > {}; template<typename Expr> struct phoenix_expr< Expr , typename enable_if<proto::matches<Expr, IfGrammar> >::type
: proto::extends<Expr, phoenix_expr, phoenix_domain> { // default phoenix stuff here, including // operator() terminal<phoenix::tag::else_>::type const else_; }; Obviously, you'd want to structure this such that both the primary template and the specialization inherit from a common base which has the operator() overloads and any other stuff that would be common to them. HTH, -- Eric Niebler Boost Consulting www.boost-consulting.com