Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r55613 - in trunk: boost/spirit/repository/home/karma/nonterminal boost/spirit/repository/home/qi/nonterminal libs/spirit/repository/test/karma libs/spirit/repository/test/qi
From: frabar666_at_[hidden]
Date: 2009-08-16 09:43:13


Author: fbarel
Date: 2009-08-16 09:43:12 EDT (Sun, 16 Aug 2009)
New Revision: 55613
URL: http://svn.boost.org/trac/boost/changeset/55613

Log:
Spirit: make inherited attributes work with multiple subrules
Text files modified:
   trunk/boost/spirit/repository/home/karma/nonterminal/subrule.hpp | 146 ++++-----------------------------------
   trunk/boost/spirit/repository/home/qi/nonterminal/subrule.hpp | 146 ++++-----------------------------------
   trunk/libs/spirit/repository/test/karma/subrule.cpp | 23 ------
   trunk/libs/spirit/repository/test/qi/subrule.cpp | 9 -
   4 files changed, 33 insertions(+), 291 deletions(-)

Modified: trunk/boost/spirit/repository/home/karma/nonterminal/subrule.hpp
==============================================================================
--- trunk/boost/spirit/repository/home/karma/nonterminal/subrule.hpp (original)
+++ trunk/boost/spirit/repository/home/karma/nonterminal/subrule.hpp 2009-08-16 09:43:12 EDT (Sun, 16 Aug 2009)
@@ -30,9 +30,6 @@
 #include <boost/fusion/include/as_map.hpp>
 #include <boost/fusion/include/at_key.hpp>
 #include <boost/fusion/include/cons.hpp>
-#include <boost/fusion/include/end.hpp>
-#include <boost/fusion/include/find_if.hpp>
-#include <boost/fusion/include/fold.hpp>
 #include <boost/fusion/include/front.hpp>
 #include <boost/fusion/include/has_key.hpp>
 #include <boost/fusion/include/join.hpp>
@@ -54,21 +51,6 @@
 #endif
 
 ///////////////////////////////////////////////////////////////////////////////
-namespace boost { namespace spirit
-{
- ///////////////////////////////////////////////////////////////////////////
- // Enablers
- ///////////////////////////////////////////////////////////////////////////
- template <>
- struct use_operator<karma::domain, proto::tag::comma> // enables ,
- : mpl::true_ {};
-
- template <>
- struct flatten_tree<karma::domain, proto::tag::comma> // flattens ,
- : mpl::true_ {};
-}}
-
-///////////////////////////////////////////////////////////////////////////////
 namespace boost { namespace spirit { namespace repository { namespace karma
 {
     ///////////////////////////////////////////////////////////////////////////
@@ -115,7 +97,7 @@
         {
         }
 
- subrule_group(Defs const& defs)
+ explicit subrule_group(Defs const& defs)
           : base_type(terminal::make(reference_(*this)))
           , defs(defs)
         {
@@ -270,6 +252,20 @@
             return fusion::front(defs).second.binder.g.what(context);
         }
 
+ template <typename Defs2>
+ subrule_group<
+ typename fusion::result_of::as_map<
+ typename fusion::result_of::join<
+ Defs const, Defs2 const>::type>::type>
+ operator,(subrule_group<Defs2> const& other) const
+ {
+ typedef subrule_group<
+ typename fusion::result_of::as_map<
+ typename fusion::result_of::join<
+ Defs const, Defs2 const>::type>::type> result_type;
+ return result_type(fusion::as_map(fusion::join(defs, other.defs)));
+ }
+
         // bring in the operator() overloads
         this_type const& get_parameterized_subject() const { return *this; }
         typedef this_type parameterized_subject_type;
@@ -554,118 +550,6 @@
     };
 }}}}
 
-///////////////////////////////////////////////////////////////////////////////
-namespace boost { namespace spirit { namespace karma
-{
- ///////////////////////////////////////////////////////////////////////////
- // Generator generators: make_xxx function (objects)
- ///////////////////////////////////////////////////////////////////////////
- template <typename Elements, typename Modifiers>
- struct make_composite<proto::tag::comma, Elements, Modifiers>
- {
- // Elements is a Fusion sequence of reference<subrule_group<...> const>
-
-
- ///////////////////////////////////////////////////////////////////////
- // 1. confirm that, to avoid further confusion if it is not the case
-
- // this check is done with a metafunction class instead of an MPL
- // lambda expression with placeholders for the sake of gcc-3.x
- struct is_not_subrule_group
- {
- template <typename T>
- struct apply
- {
- typedef mpl::true_ type;
- };
- template <typename Defs>
- struct apply<reference<
- spirit::repository::karma::subrule_group<Defs> const> >
- {
- typedef mpl::false_ type;
- };
- };
-
- // If you are seeing a compilation error here, you are using a comma
- // (,) for something other than separating definitions of subrules.
- BOOST_SPIRIT_ASSERT_MSG(
- (is_same<
- typename fusion::result_of::find_if<Elements
- , is_not_subrule_group>::type,
- typename fusion::result_of::end<Elements>::type>::value)
- , comma_not_separating_subrule_definitions, (Elements));
-
-
- ///////////////////////////////////////////////////////////////////////
- // 2. merge subrule groups together
-
- // function object applied on each element (reference to subrule_group)
- // with fusion::fold to compute the map of definitions for the
- // merged subrule_group
- struct merge_defs
- {
- template <typename Element, typename State>
- struct result_
- {
- // Note: it is not checked that any subrule is defined at most
- // once within a group (i.e. that keys are unique when joining
- // the two maps). If needed, this check could be added here.
-
- typedef
- typename fusion::result_of::join<
- State const
- , typename Element::subject_type::defs_type const
- >::type
- type;
- };
-
- template <typename Signature>
- struct result;
- template <typename Self, typename Element, typename State>
- struct result<Self(Element, State)>
- : result_<
- typename remove_reference<Element>::type
- , typename remove_reference<State>::type> {};
-
- template <typename Element, typename State>
- typename result_<Element, State>::type
- operator()(Element const& element, State const& state)
- {
- typedef typename
- result_<Element, State>::type result_type;
-
- return fusion::join(
- state
- , element.ref.get().defs);
- }
- };
-
- typedef
- typename fusion::result_of::fold<
- Elements
- , typename fusion::result_of::make_map<>::type
- , merge_defs>::type
- merged_defs_type;
-
- typedef typename
- fusion::result_of::as_map<merged_defs_type>::type defs_type;
-
-
- typedef spirit::repository::karma::subrule_group<
- defs_type> result_type;
-
- result_type operator()(Elements const& elements, unused_type) const
- {
- return result_type(
- fusion::as_map(
- fusion::fold(
- elements
- , fusion::make_map()
- , merge_defs())));
- }
- };
-}}}
-
 #if defined(BOOST_MSVC)
 # pragma warning(pop)
 #endif

Modified: trunk/boost/spirit/repository/home/qi/nonterminal/subrule.hpp
==============================================================================
--- trunk/boost/spirit/repository/home/qi/nonterminal/subrule.hpp (original)
+++ trunk/boost/spirit/repository/home/qi/nonterminal/subrule.hpp 2009-08-16 09:43:12 EDT (Sun, 16 Aug 2009)
@@ -30,9 +30,6 @@
 #include <boost/fusion/include/as_map.hpp>
 #include <boost/fusion/include/at_key.hpp>
 #include <boost/fusion/include/cons.hpp>
-#include <boost/fusion/include/end.hpp>
-#include <boost/fusion/include/find_if.hpp>
-#include <boost/fusion/include/fold.hpp>
 #include <boost/fusion/include/front.hpp>
 #include <boost/fusion/include/has_key.hpp>
 #include <boost/fusion/include/join.hpp>
@@ -54,21 +51,6 @@
 #endif
 
 ///////////////////////////////////////////////////////////////////////////////
-namespace boost { namespace spirit
-{
- ///////////////////////////////////////////////////////////////////////////
- // Enablers
- ///////////////////////////////////////////////////////////////////////////
- template <>
- struct use_operator<qi::domain, proto::tag::comma> // enables ,
- : mpl::true_ {};
-
- template <>
- struct flatten_tree<qi::domain, proto::tag::comma> // flattens ,
- : mpl::true_ {};
-}}
-
-///////////////////////////////////////////////////////////////////////////////
 namespace boost { namespace spirit { namespace repository { namespace qi
 {
     ///////////////////////////////////////////////////////////////////////////
@@ -109,7 +91,7 @@
         {
         }
 
- subrule_group(Defs const& defs)
+ explicit subrule_group(Defs const& defs)
           : base_type(terminal::make(reference_(*this)))
           , defs(defs)
         {
@@ -271,6 +253,20 @@
             return fusion::front(defs).second.binder.p.what(context);
         }
 
+ template <typename Defs2>
+ subrule_group<
+ typename fusion::result_of::as_map<
+ typename fusion::result_of::join<
+ Defs const, Defs2 const>::type>::type>
+ operator,(subrule_group<Defs2> const& other) const
+ {
+ typedef subrule_group<
+ typename fusion::result_of::as_map<
+ typename fusion::result_of::join<
+ Defs const, Defs2 const>::type>::type> result_type;
+ return result_type(fusion::as_map(fusion::join(defs, other.defs)));
+ }
+
         // bring in the operator() overloads
         this_type const& get_parameterized_subject() const { return *this; }
         typedef this_type parameterized_subject_type;
@@ -549,118 +545,6 @@
     };
 }}}}
 
-///////////////////////////////////////////////////////////////////////////////
-namespace boost { namespace spirit { namespace qi
-{
- ///////////////////////////////////////////////////////////////////////////
- // Parser generators: make_xxx function (objects)
- ///////////////////////////////////////////////////////////////////////////
- template <typename Elements, typename Modifiers>
- struct make_composite<proto::tag::comma, Elements, Modifiers>
- {
- // Elements is a Fusion sequence of reference<subrule_group<...> const>
-
-
- ///////////////////////////////////////////////////////////////////////
- // 1. confirm that, to avoid further confusion if it is not the case
-
- // this check is done with a metafunction class instead of an MPL
- // lambda expression with placeholders for the sake of gcc-3.x
- struct is_not_subrule_group
- {
- template <typename T>
- struct apply
- {
- typedef mpl::true_ type;
- };
- template <typename Defs>
- struct apply<reference<
- spirit::repository::qi::subrule_group<Defs> const> >
- {
- typedef mpl::false_ type;
- };
- };
-
- // If you are seeing a compilation error here, you are using a comma
- // (,) for something other than separating definitions of subrules.
- BOOST_SPIRIT_ASSERT_MSG(
- (is_same<
- typename fusion::result_of::find_if<Elements
- , is_not_subrule_group>::type,
- typename fusion::result_of::end<Elements>::type>::value)
- , comma_not_separating_subrule_definitions, (Elements));
-
-
- ///////////////////////////////////////////////////////////////////////
- // 2. merge subrule groups together
-
- // function object applied on each element (reference to subrule_group)
- // with fusion::fold to compute the map of definitions for the
- // merged subrule_group
- struct merge_defs
- {
- template <typename Element, typename State>
- struct result_
- {
- // Note: it is not checked that any subrule is defined at most
- // once within a group (i.e. that keys are unique when joining
- // the two maps). If needed, this check could be added here.
-
- typedef
- typename fusion::result_of::join<
- State const
- , typename Element::subject_type::defs_type const
- >::type
- type;
- };
-
- template <typename Signature>
- struct result;
- template <typename Self, typename Element, typename State>
- struct result<Self(Element, State)>
- : result_<
- typename remove_reference<Element>::type
- , typename remove_reference<State>::type> {};
-
- template <typename Element, typename State>
- typename result_<Element, State>::type
- operator()(Element const& element, State const& state)
- {
- typedef typename
- result_<Element, State>::type result_type;
-
- return fusion::join(
- state
- , element.ref.get().defs);
- }
- };
-
- typedef
- typename fusion::result_of::fold<
- Elements
- , typename fusion::result_of::make_map<>::type
- , merge_defs>::type
- merged_defs_type;
-
- typedef typename
- fusion::result_of::as_map<merged_defs_type>::type defs_type;
-
-
- typedef spirit::repository::qi::subrule_group<
- defs_type> result_type;
-
- result_type operator()(Elements const& elements, unused_type) const
- {
- return result_type(
- fusion::as_map(
- fusion::fold(
- elements
- , fusion::make_map()
- , merge_defs())));
- }
- };
-}}}
-
 #if defined(BOOST_MSVC)
 # pragma warning(pop)
 #endif

Modified: trunk/libs/spirit/repository/test/karma/subrule.cpp
==============================================================================
--- trunk/libs/spirit/repository/test/karma/subrule.cpp (original)
+++ trunk/libs/spirit/repository/test/karma/subrule.cpp 2009-08-16 09:43:12 EDT (Sun, 16 Aug 2009)
@@ -127,28 +127,6 @@
         BOOST_TEST(test_delimited("12.4 ", start, v, space));
     }
 
-#if 0
-/*
-FIXME groups with multiple subrules don't work with inherited attributes
-because the situation is not like for rules/grammars/terminal_ex where
-the inherited attributes are an invocation of "operator()" on a customized
-proto terminal.
- (
- sr1 = ...
- , sr2 = ...
- )(a1, a2)
-Here the "target" of the "(a1, a2)" function call is a proto expr (list
-of proto::tag::comma), not yet compiled into a subrule_group which exposes
-an "operator()". So the inherited attributes are seen as a proto expr too
-(proto::tag::function) and compile stops there.
-
-See if:
-- either proto::tag::function can be handled somehow (would make
- handling of inherited attributes different for subrules than
- for rules/grammars/terminal_ex, probably not a good idea),
-- or rather if "operator," can be overloaded on subrule_group,
- instead of having it handled by use_operator/make_composite.
-*/
     {
         rule<outiter_type, void(char, int, double)> start;
         subrule<0, void(char, int, double)> sr;
@@ -202,7 +180,6 @@
         )(_r1, _r2, _r3);
         BOOST_TEST(test_delimited("a 10 12.4 ", start('a', 10, 12.4), space));
     }
-#endif
 
     return boost::report_errors();
 }

Modified: trunk/libs/spirit/repository/test/qi/subrule.cpp
==============================================================================
--- trunk/libs/spirit/repository/test/qi/subrule.cpp (original)
+++ trunk/libs/spirit/repository/test/qi/subrule.cpp 2009-08-16 09:43:12 EDT (Sun, 16 Aug 2009)
@@ -259,15 +259,12 @@
         )(1, 2), ch));
         BOOST_TEST(ch == 'a' + 1 + 2);
 
-#if 0 // doesn't work yet, see comment in karma/subrule.cpp
         // multiple subrules + args
- subrule<2, char(int, int)> sr2;
- BOOST_TEST(test_attr("ac", (
- sr2 = alpha[_val = _1 + _r1 + _r2] >> sr1(3)[_val += _1]
+ BOOST_TEST(test_attr("ba", (
+ sr2 = alpha[_val = _1 + _r1 + _r2] >> sr1(3)[_val -= _1]
           , sr1 = alpha[_val = _1 + _r1]
         )(1, 2), ch));
- BOOST_TEST(ch == 'a' + 1 + 2 + 'c' + 3);
-#endif
+ BOOST_TEST(ch == ('b' + 1 + 2) - ('a' + 3));
     }
 
     { // context (w/ reference arg) tests


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk