Boost logo

Boost :

From: Maurizio Vitale (mav_at_[hidden])
Date: 2007-06-14 11:29:49


This one took me a long time to understand, and now that I think I understand it, I'm pretty sure I don't like

Apparently (at least in the situation shown below, with user defined domain and expressions) unary_expr matches
terminal< >. This was surprising to me because I was working under the assumption that unary_expr matched only
bona-fide unary C++ operators. Ordering should have solved the problem in my real code, so I still have
investigations to do.

In my case I need to match both things, but threat the case separately (e.g. a terminal<foo> will be transfromed differently from a
terminal<bar> and even more differently from ++a).
Now, I can certainly (I think, not tested) wrap unary_expr in a proto::and_ that tests the tag, but it seems such a common
occurrence that I'd like it to be the default proto behaviour.

Unless I'm doing something stupid.

Regards,

       Maurizio

===File ~/dev/proto_pdl/pe4.cpp=============================
#define BOOST_PROTO_MAX_ARITY 10
#define BOOST_MPL_LIMIT_METAFUNCTION_ARITY 10
#include <iostream>
#include <boost/xpressive/proto/proto.hpp>
#include <boost/xpressive/proto/debug.hpp>

namespace proto=boost::proto;

template<typename> struct meta_expression;

struct meta_domain : proto::domain<proto::generator<meta_expression> > {};

template <typename Expr>
struct meta_expression : proto::extends<Expr, meta_expression<Expr>, meta_domain> {
  typedef proto::extends<Expr, meta_expression<Expr>, meta_domain> base_type;

    
  meta_expression (Expr const& expr = Expr()) : base_type (expr) {}

  using base_type::operator =;
};

#define META_TERMINAL(NAME) \
  struct NAME##_tag {}; \
  inline char const* proto_tag_name (NAME##_tag) { return #NAME; } \
  std::ostream& operator << (std::ostream& os, const NAME##_tag) { os << "[" #NAME "]" ; return os; } \
  meta_expression<proto::terminal<NAME##_tag>::type> NAME

struct _5_tag {};
inline const char* proto_tag_name (_5_tag) {return "_5"; }
meta_expression<proto::terminal<_5_tag>::type> _5;

//
  std::ostream& operator << (std::ostream& os, const _5_tag) { os << "[_5]" ; return os; } \

META_TERMINAL (_1);
META_TERMINAL (_2);
META_TERMINAL (_3);

struct meta_grammar : proto::or_ <
  proto::terminal<_1_tag>,
// proto::terminal<_2_tag>,
  proto::terminal<_3_tag>,
  proto::unary_expr<proto::_, proto::_>
>
{};

template<typename Expr>
void is_meta_expression (const Expr& expr) {
  std::cout << "Expression:\n";
  proto::display_expr (expr);
    if (proto::matches<Expr, meta_grammar>::value)
    std::cout << "matches meta grammar\n\n";
  else
    std::cout << "doesn't matches meta grammar\n\n";
}

int main (int,char**) {
  is_meta_expression (_2);
}

/// Local Variables:
/// mode:c++
/// comment-column:60
/// fill-column:150
/// compilation-read-command:nil
/// compile-command:"g++ -I. -ope4 pe4.cpp"
/// End:

============================================================


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk