Re: [proto] [Proto]: How to use complex grammars in a domain/extension

2010-09-22 Thread Thomas Heller



Eric Niebler wrote:

 On 9/21/2010 9:51 AM, Eric Niebler wrote:
 (proto lists members, see this thread for the rest of the discussion,
 which has been happening on -users:
 http://lists.boost.org/boost-users/2010/09/62747.php)
 
 On 9/21/2010 9:19 AM, Roland Bock wrote:
 On 09/21/2010 11:55 AM, Thomas Heller wrote:
 snip
 Solved the mistery. here is the code, explanation comes afterward:

 snip
 So, everything works as expected!

 Thomas,

 wow, this was driving me crazy, thanks for solving and explaining in all
 the detail! :-)

 I am still not sure if this isn't a conceptual problem, though:

 The equation grammar is perfectly OK. But without or-ing it with the
 addition grammar, the extension does not allow ANY valid expression to
 be created. I wonder if that is a bug or a feature?
 
 It's a feature. Imagine this grammar:
 
 struct IntsOnlyPlease
   : proto::or_
 proto::terminalint
   , proto::nary_exprproto::_, proto::varargIntsOnlyPlease 
 
 {};
 
 And a integer terminal i in a domain that obeys this grammar. Now,
 what should this do:
 
 i + hello!;
 
 You want it to fail because if it doesn't, you would create an
 expression that doesn't conform to the domain's grammar. Right? Proto
 accomplishes this by enforcing that all operands must conform to the
 domain's grammar *and* the resulting expression must also conform.
 Otherwise, the operator is disabled.
 
 Anything else would be fundamentally broken.
 
 This explanation is incomplete. Naturally, this operator+ would be
 disabled anyway because the resulting expression doesn't conform to the
 grammar regardless of whether the LHS and RHS conform. It's a question
 of *when* the operator gets disabled. For a full explanation, see this
 bug report:
 
 https://svn.boost.org/trac/boost/ticket/2407
 
 The answer is simple and logically consistent: make sure *every* valid
 expression in your domain (including lone terminals) is accounted for by
 your grammar.

Let me add something:

The more I thought i about the problem, the more i thought that this would 
be a perfect use case for sub domains! So i tried to hack something 
together:

#includeboost/proto/proto.hpp

using namespace boost;

typedef proto::terminalint::type const terminal;

struct equation;

struct addition:
proto::or_

   proto::terminalproto::_,
   proto::plusaddition, addition

{};

struct equation:
proto::or_

proto::equal_toaddition, addition

{};

templateclass Expr
struct extension;

struct my_domain:
proto::domain

 proto::pod_generatorextension,
 proto::or_equation, addition,
 proto::default_domain

{};

templateclass Expr
struct lhs_extension;

struct my_lhs_domain:
proto::domain

proto::pod_generatorlhs_extension,
addition,
my_domain

{};

templateclass Expr
struct rhs_extension;

struct my_rhs_domain:
proto::domain

proto::pod_generatorrhs_extension,
addition,
my_domain

{};


templateclass Expr
struct extension
{
 BOOST_PROTO_BASIC_EXTENDS(
 Expr
   , extensionExpr
   , my_domain
 )

void test() const
{}
};

templateclass Expr
struct lhs_extension
{
 BOOST_PROTO_BASIC_EXTENDS(
 Expr
   , lhs_extensionExpr
   , my_lhs_domain
 )
};

templateclass Expr
struct rhs_extension
{
 BOOST_PROTO_BASIC_EXTENDS(
 Expr
   , rhs_extensionExpr
   , my_rhs_domain
 )
};

template typename Grammar, typename Expr
void matches(Expr const expr)
{
expr.test();

 std::cout  std::boolalpha
  proto::matchesExpr, Grammar::value  \n;
}

int main()
{
 lhs_extensionterminal const i = {};
 rhs_extensionterminal const j = {};


 /*matchesequation(i);  // false
 matchesequation(j);  // false
 matchesequation(i + i);  // false
 matchesequation(j + j);  // false*/
 //matchesequation(i + j);  // compile error
 //matchesequation(j + i);  // compile error
 matchesequation(i == j); // true
 matchesequation(i == j + j); // true
 matchesequation(i + i == j); // true
 matchesequation(i + i == j + j); // true
}

This seems to be exactly what Roland wanted to achieve in the first place.
However, it looks like this design just overcomplicates stuff because we 
have to specify the addition in our base domain anyway ...

Initially i was under the impression that this wasn't needed, but it seems 
that proto cannot deduce something like:

lhs_expression OP rhs_expression results in expression

So the question is: is it reasonable to add features like that?
It seems valuable to me.


___
proto mailing list
proto@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/proto


Re: [proto] question about sub-domains

2010-09-22 Thread Eric Niebler
On 9/22/2010 4:35 PM, Christophe Henry wrote:
 Hi,
 
 The subject of the day seems to be sub-domains and it's great because
 I wanted to check that a use I just made of them was correct.
 So the problem is:
 In eUML, states are terminals of my state machine domain (sm_domain).
 The domain's grammar disables as little as possible (address_of):
 
 struct terminal_grammar : proto::not_proto::address_ofproto::_ 
 {};
 
 // Forward-declare an expression wrapper
 templatetypename Expr
 struct euml_terminal;
 
 struct sm_domain
 : proto::domain proto::generatoreuml_terminal, terminal_grammar 
 {};
 
 Now, I just implemented serialization for state machines using
 boost::serialization which happens to define its own DSEL, archive 
 fsm and archive  fsm.
 As state machines are states in eUML, I created a conflict between
 both DSELs:  and  for serialization and my own eUML, like init_ 
 some_state.

Right.

 I solved the conflict by creating a sub-domain for states with a
 stricter grammar:
 
 struct state_grammar :
 proto::and_
 proto::not_proto::address_ofproto::_ ,
 proto::not_proto::shift_rightproto::_,proto::_ ,
 proto::not_proto::shift_leftproto::_,proto::_ ,
 proto::not_proto::bitwise_andproto::_,proto::_ 
 
 {};
 struct state_domain
 : proto::domain proto::generatoreuml_terminal, state_grammar,sm_domain 
 
 {};
 
 As init_ is in the super domain sm_domain, init_  state is allowed,
 but as states are in the sub-domain, archive  fsm calls the correct
 boost::serialization overload.

Clever!

 However, I have some doubt that what I'm doing really is ok or happens
 to be working by pure luck.
 If it's an acceptable usage, sub-domains helped me out of a tight spot
 and I'm really going to be tempted to push this further ;-)

This is really ok. I'm very glad this feature is finding real-world
uses. Push it further and send us status updates. :-)

-- 
Eric Niebler
BoostPro Computing
http://www.boostpro.com
___
proto mailing list
proto@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/proto