Boost logo

Boost Users :

Subject: [Boost-users] Defining Statements with Proto
From: David A. Greene (greened_at_[hidden])
Date: 2009-12-31 12:29:25


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


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net