[Proto] Limiting function arity in grammar

How can I write a grammar that accept a given set of terminal and functions with up to N arguments (for example accepting function with 1 to 5 arguments but not 6 or more) ? I believe i can count the elements of vararg using mpl::size ons ome proto::arg_ or proto::value maybe but how to prevent those who violates this condition be removed from the accepted functions et ? thanks in advance -- ___________________________________________ Joel Falcou - Assistant Professor PARALL Team - LRI - Universite Paris Sud XI Tel : (+33)1 69 15 66 35

Joel Falcou wrote:
How can I write a grammar that accept a given set of terminal and functions with up to N arguments (for example accepting function with 1 to 5 arguments but not 6 or more) ?
I believe i can count the elements of vararg using mpl::size ons ome proto::arg_ or proto::value maybe but how to prevent those who violates this condition be removed from the accepted functions et ?
thanks in advance
You can use proto::if_ with some mpl meta-functions and proto::arity_of. See below: #include <boost/mpl/less.hpp> #include <boost/mpl/long.hpp> #include <boost/mpl/assert.hpp> #include <boost/proto/proto.hpp> namespace mpl = boost::mpl; namespace proto = boost::proto; using proto::_; struct ArityLessThan3 : proto::or_< proto::terminal<_> , proto::and_< proto::function< proto::vararg<ArityLessThan3> > , proto::if_< mpl::less< proto::arity_of<_>, mpl::long_<4> >() > > > {}; template<class Expr> void assert_matches(Expr const &) { BOOST_MPL_ASSERT((proto::matches<Expr, ArityLessThan3>)); } template<class Expr> void assert_not_matches(Expr const &) { BOOST_MPL_ASSERT_NOT((proto::matches<Expr, ArityLessThan3>)); } int main() { proto::literal<int> i(0); assert_matches(i); assert_matches(i()); assert_matches(i(i)); assert_matches(i(i,i)); assert_not_matches(i(i,i,i)); } -- Eric Niebler BoostPro Computing http://www.boostpro.com

Eric Niebler a écrit :
You can use proto::if_ with some mpl meta-functions and proto::arity_of. See below: Ah, I missed that v_v Times to print out the new docs and pin it on my office walls
struct ArityLessThan3 : proto::or_< proto::terminal<_> , proto::and_< proto::function< proto::vararg<ArityLessThan3> > , proto::if_< mpl::less< proto::arity_of<_>, mpl::long_<4>
() > > > {}; Shouldn't it be : proto::function< _, proto::vararg<ArityLessThan3> > ? or does vararg also count the function tag ?
-- ___________________________________________ Joel Falcou - Assistant Professor PARALL Team - LRI - Universite Paris Sud XI Tel : (+33)1 69 15 66 35

Joel Falcou wrote:
Eric Niebler a écrit :
You can use proto::if_ with some mpl meta-functions and proto::arity_of. See below: Ah, I missed that v_v Times to print out the new docs and pin it on my office walls
struct ArityLessThan3 : proto::or_< proto::terminal<_> , proto::and_< proto::function< proto::vararg<ArityLessThan3> > , proto::if_< mpl::less< proto::arity_of<_>, mpl::long_<4>
() > > > {}; Shouldn't it be : proto::function< _, proto::vararg<ArityLessThan3> > ? or does vararg also count the function tag ?
No, proto::function< proto::vararg<X> > is equivalent to proto::nary_expr< proto::tag::function, proto::vararg<X> >. Note also that we compare to 4 instead of 3 above because Proto considers an expression like i(i,i,i) to have arity 4 ... because there are four child expressions. HTH, -- Eric Niebler BoostPro Computing http://www.boostpro.com
participants (2)
-
Eric Niebler
-
Joel Falcou