|
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