Boost logo

Boost Users :

Subject: Re: [Boost-users] [Proto] Limiting function arity in grammar
From: Eric Niebler (eric_at_[hidden])
Date: 2008-10-02 16:33:15


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

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