
Hicham Mouline wrote:
Re my constants definitions (my constant terminals are defined as proto::terminal< constant_tag<24> >::type c24; ), the allowed syntax is : c24 = const_expression; // const_expression cannot include c24
a loose EBNF for my const_expression is:
const_expression :: integer-literal e.g. 7 | floating-literal e.g. 5.4 | integer-type runtime variable e.g. int x, long y (known only at runtime) | fp runtime variable e.g. float r, double q (known only at runtime) | my DSEL constants | - const_expression | const_expression + const_expression | const_expression - const_expression | const_expression * const_expression | const_expression / const_expression | const_expression % const_expression | basic_function( const_expression ) | function( const_expression, ..., const_expression ) // respect the dimensionality
I don't see I am missing anything obvious?
I don't know, that's really for you to say as the DSEL designer.
The concept of const_expression here is not meant that the value of the expression is known at compile-time. It only means that on taking the derivatives of my functions wrt to my DSEL variables, the const_expression disappears.
In order to exclude the constant being defined from the = RHS, I need to define the grammar wholly for LHS and RHS of = at the same time, I couldn't define RHS grammar alone because I need to exclude c24, right?
Not necessarily. I would just define the RHS grammar without worrying about excluding any particular constants. Then give your constants an overloaded operator= that uses a compile-time assertion to make sure the RHS doesn't contain the constant currently being assigned. Something like (untested) ... template<class ID> struct constant : proto::extends< typename proto::terminal<constant_impl<ID> >::type , constant<ID> > { // For this constant, this grammar defines the valid // right-hand side expressions. struct RHS : proto::or_< proto::and_< proto::terminal<_> , proto::not_<proto::terminal<constant_impl<ID> > > > , proto::nary_expr<_, proto::vararg<RHS> > > {}; template<typename E> /* ... whatever you want this to return ... */ operator=(E const &e) const { // Make sure E doesn't contain the constant // currently being assigned. BOOST_MPL_ASSERT((proto::matches<E, RHS>)); /* ... whatever else you want here ... */ } }; HTH, -- Eric Niebler BoostPro Computing http://www.boostpro.com