|
Boost Users : |
Subject: Re: [Boost-users] [Proto]: How to use complex grammars in a domain/extension
From: Eric Niebler (eric_at_[hidden])
Date: 2010-09-21 09:43:06
On 9/21/2010 5:55 AM, Thomas Heller wrote:
> Solved the mistery. here is the code, explanation comes afterward:
>
> #include<boost/proto/proto.hpp>
>
> using namespace boost;
>
> typedef proto::terminal<int>::type terminal;
>
> struct addition:
> proto::or_
> <
> proto::plus<addition, addition>,
> proto::terminal<proto::_>
> >
> {};
>
> struct equation:
> proto::or_
> <
> proto::equal_to<addition, addition>
> >
> {};
>
> template<class Expr>
> struct extension;
>
> struct my_domain:
> proto::domain
> <
> proto::pod_generator< extension>,
> // we need both grammars in our domain grammar
> proto::or_<equation, addition>,
That will also work because addition (contrary to its name) will also
match lone terminals.
> proto::default_domain
> >
> {};
>
>
> template<class Expr>
> struct extension
> {
> BOOST_PROTO_EXTENDS(
> Expr
> , extension<Expr>
> , my_domain
> )
> };
>
> template <typename Grammar, typename Expr>
> void matches(Expr const&)
> {
> std::cout << std::boolalpha
> << proto::matches<Expr, Grammar>::value << "\n";
> }
>
> int main()
> {
> extension<terminal> i;
> extension<terminal> j;
>
>
> matches<equation>(i); // 1) false
> matches<equation>(i == j); // 2) true
> matches<equation>(i == i + i); // 3) true
> matches<equation>(i + i == i); // 4) true
> matches<equation>(i + i == i + i); // 5) true
> matches<equation>(i + i); // 6) false
> }
>
> Ok, what happened, why does this work, and why didn't the previous attempt
> work:
>
> the equation grammar obviously doesn't match case 1) and 6). And that is
> exactly why proto didn't generate any operator+ overload.
> In order for a proto overload to be created the following conditions must be
> true:
>
> 1) the operands must be in a compatible domain
> 2) the left hand operand and the right hand operand must match the grammar
> specified in the domain
Precisely.
> 3) the resulting expression must match the grammar specified in the domain.
Right-o.
> In our example 1) is always true. 2) and 3) are not true for expressions
> like 1) and 6). That means, that any binary operator gets disabled whenever
> the LHS or the RHS is a terminal<_>. because of the equation grammar,
> terminals or additions can not stand alone, that is why operator creation
> failed. Makes sense!
> In order to enable the operators, we just say, our domain can have addition
> _or_ equation. That's it, operator+ and operator== get enabled.
> We can still detect invalid expression with proto::matches!
>
> So, everything works as expected!
Thomas wins the prize. This is not a bug in Proto.
-- 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