Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r55545 - in trunk/boost/spirit/home: karma/nonterminal karma/nonterminal/detail qi/nonterminal qi/nonterminal/detail support/nonterminal
From: frabar666_at_[hidden]
Date: 2009-08-12 09:06:49


Author: fbarel
Date: 2009-08-12 09:06:44 EDT (Wed, 12 Aug 2009)
New Revision: 55545
URL: http://svn.boost.org/trac/boost/changeset/55545

Log:
Spirit: factor out common nonterminal stuff
Added:
   trunk/boost/spirit/home/karma/nonterminal/detail/parameterized.hpp (contents, props changed)
   trunk/boost/spirit/home/qi/nonterminal/detail/parameterized.hpp (contents, props changed)
   trunk/boost/spirit/home/support/nonterminal/extract_param.hpp (contents, props changed)
Text files modified:
   trunk/boost/spirit/home/karma/nonterminal/detail/fcall.hpp | 17 +++---
   trunk/boost/spirit/home/karma/nonterminal/detail/generator_binder.hpp | 27 ----------
   trunk/boost/spirit/home/karma/nonterminal/grammar.hpp | 5 -
   trunk/boost/spirit/home/karma/nonterminal/rule.hpp | 96 ++++++++++-----------------------------
   trunk/boost/spirit/home/qi/nonterminal/detail/fcall.hpp | 17 +++---
   trunk/boost/spirit/home/qi/nonterminal/detail/parser_binder.hpp | 30 ++----------
   trunk/boost/spirit/home/qi/nonterminal/grammar.hpp | 4
   trunk/boost/spirit/home/qi/nonterminal/rule.hpp | 93 ++++++++++----------------------------
   8 files changed, 76 insertions(+), 213 deletions(-)

Modified: trunk/boost/spirit/home/karma/nonterminal/detail/fcall.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/nonterminal/detail/fcall.hpp (original)
+++ trunk/boost/spirit/home/karma/nonterminal/detail/fcall.hpp 2009-08-12 09:06:44 EDT (Wed, 12 Aug 2009)
@@ -28,22 +28,21 @@
     typename lazy_enable_if_c<
         (params_size == N)
       , proto::terminal<
- parameterized_rule<rule_type
- , fusion::vector<BOOST_PP_ENUM_PARAMS(N, A)> >
+ spirit::karma::parameterized_nonterminal<
+ parameterized_subject_type
+ , fusion::vector<BOOST_PP_ENUM_PARAMS(N, A)> >
>
>::type
     operator()(BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& f)) const
     {
         typedef fusion::vector<BOOST_PP_ENUM_PARAMS(N, A)> vector_type;
- typedef parameterized_rule<
- rule_type
- , vector_type>
- parameterized_rule;
- typedef typename proto::terminal<parameterized_rule>::type result_type;
+ typedef spirit::karma::parameterized_nonterminal<
+ parameterized_subject_type, vector_type> parameterized_type;
+ typedef typename proto::terminal<parameterized_type>::type result_type;
 
         return result_type::make(
- parameterized_rule(
- this->get_rule()
+ parameterized_type(
+ this->get_parameterized_subject()
               , fusion::make_vector(BOOST_PP_ENUM_PARAMS(N, f)))
         );
     }

Modified: trunk/boost/spirit/home/karma/nonterminal/detail/generator_binder.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/nonterminal/detail/generator_binder.hpp (original)
+++ trunk/boost/spirit/home/karma/nonterminal/detail/generator_binder.hpp 2009-08-12 09:06:44 EDT (Wed, 12 Aug 2009)
@@ -11,16 +11,8 @@
 #pragma once
 #endif
 
-#include <utility>
-#include <boost/type_traits/remove_reference.hpp>
-#include <boost/fusion/include/value_at.hpp>
 #include <boost/fusion/include/at.hpp>
-#include <boost/type_traits/is_same.hpp>
-#include <boost/mpl/eval_if.hpp>
-#include <boost/mpl/identity.hpp>
-#include <boost/mpl/deref.hpp>
-#include <boost/mpl/end.hpp>
-#include <boost/mpl/find_if.hpp>
+#include <boost/mpl/bool.hpp>
 
 namespace boost { namespace spirit { namespace karma { namespace detail
 {
@@ -47,7 +39,7 @@
     struct generator_binder<Generator, mpl::true_>
     {
         generator_binder(Generator const& g)
- : g(g) {};
+ : g(g) {}
 
         template <typename OutputIterator, typename Delimiter, typename Context>
         bool operator()(OutputIterator& sink, Context& context
@@ -67,21 +59,6 @@
     {
         return generator_binder<Generator, Auto>(g);
     }
-
- template <typename Types, typename Pred, typename Default>
- struct extract_param
- {
- typedef typename mpl::find_if<Types, Pred>::type pos;
-
- typedef typename
- mpl::eval_if<
- is_same<pos, typename mpl::end<Types>::type>
- , mpl::identity<Default>
- , mpl::deref<pos>
- >::type
- type;
- };
-
 }}}}
 
 #endif

Added: trunk/boost/spirit/home/karma/nonterminal/detail/parameterized.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/nonterminal/detail/parameterized.hpp 2009-08-12 09:06:44 EDT (Wed, 12 Aug 2009)
@@ -0,0 +1,63 @@
+// Copyright (c) 2001-2009 Joel de Guzman
+// Copyright (c) 2001-2009 Hartmut Kaiser
+// Copyright (c) 2009 Francois Barel
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_KARMA_PARAMETERIZED_AUGUST_09_2009_0601AM)
+#define BOOST_SPIRIT_KARMA_PARAMETERIZED_AUGUST_09_2009_0601AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/ref.hpp>
+
+#include <boost/spirit/home/karma/generator.hpp>
+
+namespace boost { namespace spirit { namespace karma
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // parameterized_nonterminal: generator representing the invocation of a
+ // nonterminal, passing inherited attributes
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Subject, typename Params>
+ struct parameterized_nonterminal
+ : generator<parameterized_nonterminal<Subject, Params> >
+ {
+ typedef mpl::int_<generator_properties::all_properties> properties;
+
+ parameterized_nonterminal(Subject const& subject, Params const& params)
+ : ref(subject), params(params)
+ {
+ }
+
+ template <typename Context, typename Unused>
+ struct attribute
+ // Forward to subject.
+ : Subject::template attribute<Context, Unused> {};
+
+ template <typename OutputIterator, typename Context, typename Delimiter
+ , typename Attribute>
+ bool generate(OutputIterator& sink, Context& context
+ , Delimiter const& delim, Attribute const& attr) const
+ {
+ // Forward to subject, passing the additional
+ // params argument to generate.
+ return ref.get().generate(sink, context, delim, attr, params);
+ }
+
+ template <typename Context>
+ info what(Context& context) const
+ {
+ // Forward to subject.
+ return ref.get().what(context);
+ }
+
+ boost::reference_wrapper<Subject const> ref;
+ Params params;
+ };
+}}}
+
+#endif

Modified: trunk/boost/spirit/home/karma/nonterminal/grammar.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/nonterminal/grammar.hpp (original)
+++ trunk/boost/spirit/home/karma/nonterminal/grammar.hpp 2009-08-12 09:06:44 EDT (Wed, 12 Aug 2009)
@@ -83,10 +83,9 @@
         }
 
         // bring in the operator() overloads
- start_type const& get_rule() const
+ start_type const& get_parameterized_subject() const
         { return this->proto_base().child0.ref.get(); }
-
- typedef start_type rule_type;
+ typedef start_type parameterized_subject_type;
         #include <boost/spirit/home/karma/nonterminal/detail/fcall.hpp>
 
         std::string name_;

Modified: trunk/boost/spirit/home/karma/nonterminal/rule.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/nonterminal/rule.hpp (original)
+++ trunk/boost/spirit/home/karma/nonterminal/rule.hpp 2009-08-12 09:06:44 EDT (Wed, 12 Aug 2009)
@@ -13,14 +13,13 @@
 
 #include <boost/assert.hpp>
 #include <boost/function.hpp>
-#include <boost/mpl/eval_if.hpp>
-#include <boost/function_types/result_type.hpp>
-#include <boost/function_types/parameter_types.hpp>
-#include <boost/function_types/is_function.hpp>
-#include <boost/type_traits/remove_reference.hpp>
+#include <boost/mpl/vector.hpp>
+#include <boost/type_traits/add_const.hpp>
+#include <boost/type_traits/add_reference.hpp>
 #include <boost/utility/enable_if.hpp>
 
 #include <boost/fusion/include/vector.hpp>
+#include <boost/fusion/include/size.hpp>
 #include <boost/fusion/include/make_vector.hpp>
 #include <boost/fusion/include/cons.hpp>
 #include <boost/fusion/include/as_list.hpp>
@@ -31,10 +30,12 @@
 #include <boost/spirit/home/support/context.hpp>
 #include <boost/spirit/home/support/info.hpp>
 #include <boost/spirit/home/support/attributes.hpp>
+#include <boost/spirit/home/support/nonterminal/extract_param.hpp>
 #include <boost/spirit/home/support/nonterminal/locals.hpp>
 #include <boost/spirit/home/karma/reference.hpp>
 #include <boost/spirit/home/karma/detail/output_iterator.hpp>
 #include <boost/spirit/home/karma/nonterminal/detail/generator_binder.hpp>
+#include <boost/spirit/home/karma/nonterminal/detail/parameterized.hpp>
 
 namespace boost { namespace spirit { namespace karma
 {
@@ -56,36 +57,6 @@
     using spirit::info;
     using spirit::locals;
 
- template <typename Rule, typename Params>
- struct parameterized_rule : generator<parameterized_rule<Rule, Params> >
- {
- typedef mpl::int_<generator_properties::all_properties> properties;
-
- parameterized_rule(Rule const& rule, Params const& params)
- : ref(rule), params(params) {}
-
- template <typename Context, typename Unused>
- struct attribute : Rule::template attribute<Context, Unused> {};
-
- template <typename OutputIterator, typename Context, typename Delimiter
- , typename Attribute>
- bool generate(OutputIterator& sink, Context& context
- , Delimiter const& delim, Attribute const& attr) const
- {
- // We pass the additional params argument to parse
- return ref.get().generate(sink, context, delim, attr, params);
- }
-
- template <typename Context>
- info what(Context& context) const
- {
- return ref.get().what(context);
- }
-
- boost::reference_wrapper<Rule const> ref;
- Params params;
- };
-
     template <
         typename OutputIterator
       , typename T1 = unused_type
@@ -115,44 +86,23 @@
             output_iterator;
 
         // locals_type is a sequence of types to be used as local variables
- typedef typename fusion::result_of::as_vector<
- typename detail::extract_param<
- template_params
- , spirit::detail::is_locals<mpl::_>
- , locals<>
- >::type
- >::type
+ typedef typename
+ spirit::detail::extract_locals<template_params>::type
         locals_type;
 
         // The delimiter-generator type
         typedef typename
- result_of::compile<
- karma::domain
- , typename detail::extract_param<
- template_params
- , traits::matches<karma::domain, mpl::_>
- , unused_type
- >::type
- >::type
+ spirit::detail::extract_component<
+ karma::domain, template_params>::type
         delimiter_type;
 
         typedef typename
- detail::extract_param<
- template_params
- , function_types::is_function<mpl::_>
- , void()
- >::type
+ spirit::detail::extract_sig<template_params>::type
         sig_type;
 
- typedef typename function_types::result_type<sig_type>::type attr_type_;
-
         // This is the rule's attribute type
         typedef typename
- mpl::if_<
- is_same<attr_type_, void>
- , unused_type
- , attr_type_
- >::type
+ spirit::detail::attr_from_sig<sig_type>::type
         attr_type;
         typedef typename add_reference<
             typename add_const<attr_type>::type>::type
@@ -160,19 +110,17 @@
 
         // parameter_types is a sequence of types passed as parameters to the rule
         typedef typename
- function_types::parameter_types<sig_type>::type
- params_;
-
- typedef typename
- fusion::result_of::as_list<params_>::type
+ spirit::detail::params_from_sig<sig_type>::type
         parameter_types;
 
- static size_t const params_size = mpl::size<params_>::value;
+ static size_t const params_size =
+ fusion::result_of::size<parameter_types>::type::value;
 
         // the context passed to the right hand side of a rule contains
         // the attribute and the parameters for this particular rule invocation
         typedef context<
- fusion::cons<attr_reference_type, parameter_types>, locals_type>
+ fusion::cons<attr_reference_type, parameter_types>
+ , locals_type>
         context_type;
 
         typedef function<
@@ -276,6 +224,9 @@
                 typedef traits::make_attribute<attr_type, Attribute>
                     make_attribute;
 
+ // If you are seeing a compilation error here, you are probably
+ // trying to use a rule or a grammar which has inherited
+ // attributes, without passing values for them.
                 context_type context(make_attribute::call(attr));
 
                 // If you are seeing a compilation error here stating that the
@@ -302,6 +253,9 @@
                 typedef traits::make_attribute<attr_type, Attribute>
                     make_attribute;
 
+ // If you are seeing a compilation error here, you are probably
+ // trying to use a rule or a grammar which has inherited
+ // attributes, passing values of incompatible types for them.
                 context_type context(make_attribute::call(attr), params, caller_context);
 
                 // If you are seeing a compilation error here stating that the
@@ -334,8 +288,8 @@
         }
 
         // bring in the operator() overloads
- rule const& get_rule() const { return *this; }
- typedef this_type rule_type;
+ rule const& get_parameterized_subject() const { return *this; }
+ typedef rule parameterized_subject_type;
         #include <boost/spirit/home/karma/nonterminal/detail/fcall.hpp>
 
         std::string name_;

Modified: trunk/boost/spirit/home/qi/nonterminal/detail/fcall.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/nonterminal/detail/fcall.hpp (original)
+++ trunk/boost/spirit/home/qi/nonterminal/detail/fcall.hpp 2009-08-12 09:06:44 EDT (Wed, 12 Aug 2009)
@@ -28,22 +28,21 @@
     typename lazy_enable_if_c<
         (params_size == N)
       , proto::terminal<
- parameterized_rule<rule_type
- , fusion::vector<BOOST_PP_ENUM_PARAMS(N, A)> >
+ spirit::qi::parameterized_nonterminal<
+ parameterized_subject_type
+ , fusion::vector<BOOST_PP_ENUM_PARAMS(N, A)> >
>
>::type
     operator()(BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& f)) const
     {
         typedef fusion::vector<BOOST_PP_ENUM_PARAMS(N, A)> vector_type;
- typedef parameterized_rule<
- rule_type
- , vector_type>
- parameterized_rule;
- typedef typename proto::terminal<parameterized_rule>::type result_type;
+ typedef spirit::qi::parameterized_nonterminal<
+ parameterized_subject_type, vector_type> parameterized_type;
+ typedef typename proto::terminal<parameterized_type>::type result_type;
 
         return result_type::make(
- parameterized_rule(
- this->get_rule()
+ parameterized_type(
+ this->get_parameterized_subject()
               , fusion::make_vector(BOOST_PP_ENUM_PARAMS(N, f)))
         );
     }

Added: trunk/boost/spirit/home/qi/nonterminal/detail/parameterized.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/nonterminal/detail/parameterized.hpp 2009-08-12 09:06:44 EDT (Wed, 12 Aug 2009)
@@ -0,0 +1,62 @@
+/*=============================================================================
+ Copyright (c) 2001-2009 Joel de Guzman
+ Copyright (c) 2009 Francois Barel
+
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_SPIRIT_PARAMETERIZED_AUGUST_09_2009_0539AM)
+#define BOOST_SPIRIT_PARAMETERIZED_AUGUST_09_2009_0539AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/ref.hpp>
+
+#include <boost/spirit/home/qi/parser.hpp>
+
+namespace boost { namespace spirit { namespace qi
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // parameterized_nonterminal: parser representing the invocation of a
+ // nonterminal, passing inherited attributes
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Subject, typename Params>
+ struct parameterized_nonterminal
+ : parser<parameterized_nonterminal<Subject, Params> >
+ {
+ parameterized_nonterminal(Subject const& subject, Params const& params)
+ : ref(subject), params(params)
+ {
+ }
+
+ template <typename Context, typename Iterator>
+ struct attribute
+ // Forward to subject.
+ : Subject::template attribute<Context, Iterator> {};
+
+ template <typename Iterator, typename Context
+ , typename Skipper, typename Attribute>
+ bool parse(Iterator& first, Iterator const& last
+ , Context& context, Skipper const& skipper
+ , Attribute& attr) const
+ {
+ // Forward to subject, passing the additional
+ // params argument to parse.
+ return ref.get().parse(first, last, context, skipper, attr, params);
+ }
+
+ template <typename Context>
+ info what(Context& context) const
+ {
+ // Forward to subject.
+ return ref.get().what(context);
+ }
+
+ boost::reference_wrapper<Subject const> ref;
+ Params params;
+ };
+}}}
+
+#endif

Modified: trunk/boost/spirit/home/qi/nonterminal/detail/parser_binder.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/nonterminal/detail/parser_binder.hpp (original)
+++ trunk/boost/spirit/home/qi/nonterminal/detail/parser_binder.hpp 2009-08-12 09:06:44 EDT (Wed, 12 Aug 2009)
@@ -11,16 +11,8 @@
 #pragma once
 #endif
 
-#include <utility>
-#include <boost/type_traits/remove_reference.hpp>
-#include <boost/fusion/include/value_at.hpp>
 #include <boost/fusion/include/at.hpp>
-#include <boost/type_traits/is_same.hpp>
-#include <boost/mpl/eval_if.hpp>
-#include <boost/mpl/identity.hpp>
-#include <boost/mpl/deref.hpp>
-#include <boost/mpl/end.hpp>
-#include <boost/mpl/find_if.hpp>
+#include <boost/mpl/bool.hpp>
 
 namespace boost { namespace spirit { namespace qi { namespace detail
 {
@@ -29,7 +21,7 @@
     struct parser_binder
     {
         parser_binder(Parser const& p)
- : p(p) {};
+ : p(p) {}
 
         template <typename Iterator, typename Skipper, typename Context>
         bool operator()(
@@ -39,6 +31,7 @@
             // If Auto is false, the component's attribute is unused.
             return p.parse(first, last, context, skipper, unused);
         }
+
         Parser p;
     };
 
@@ -47,7 +40,7 @@
     struct parser_binder<Parser, mpl::true_>
     {
         parser_binder(Parser const& p)
- : p(p) {};
+ : p(p) {}
 
         template <typename Iterator, typename Skipper, typename Context>
         bool operator()(
@@ -58,6 +51,7 @@
             return p.parse(first, last, context, skipper
                 , fusion::at_c<0>(context.attributes));
         }
+
         Parser p;
     };
 
@@ -67,20 +61,6 @@
     {
         return parser_binder<Parser, Auto>(p);
     }
-
- template <typename Types, typename Pred, typename Default>
- struct extract_param
- {
- typedef typename mpl::find_if<Types, Pred>::type pos;
-
- typedef typename
- mpl::eval_if<
- is_same<pos, typename mpl::end<Types>::type>
- , mpl::identity<Default>
- , mpl::deref<pos>
- >::type
- type;
- };
 }}}}
 
 #endif

Modified: trunk/boost/spirit/home/qi/nonterminal/grammar.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/nonterminal/grammar.hpp (original)
+++ trunk/boost/spirit/home/qi/nonterminal/grammar.hpp 2009-08-12 09:06:44 EDT (Wed, 12 Aug 2009)
@@ -80,9 +80,9 @@
         }
 
         // bring in the operator() overloads
- start_type const& get_rule() const
+ start_type const& get_parameterized_subject() const
         { return this->proto_base().child0.ref.get(); }
- typedef start_type rule_type;
+ typedef start_type parameterized_subject_type;
         #include <boost/spirit/home/qi/nonterminal/detail/fcall.hpp>
 
         std::string name_;

Modified: trunk/boost/spirit/home/qi/nonterminal/rule.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/nonterminal/rule.hpp (original)
+++ trunk/boost/spirit/home/qi/nonterminal/rule.hpp 2009-08-12 09:06:44 EDT (Wed, 12 Aug 2009)
@@ -13,14 +13,12 @@
 
 #include <boost/assert.hpp>
 #include <boost/function.hpp>
-#include <boost/mpl/eval_if.hpp>
-#include <boost/function_types/result_type.hpp>
-#include <boost/function_types/parameter_types.hpp>
-#include <boost/function_types/is_function.hpp>
-#include <boost/type_traits/remove_reference.hpp>
+#include <boost/mpl/vector.hpp>
+#include <boost/type_traits/add_reference.hpp>
 #include <boost/utility/enable_if.hpp>
 
 #include <boost/fusion/include/vector.hpp>
+#include <boost/fusion/include/size.hpp>
 #include <boost/fusion/include/make_vector.hpp>
 #include <boost/fusion/include/cons.hpp>
 #include <boost/fusion/include/as_list.hpp>
@@ -31,8 +29,10 @@
 #include <boost/spirit/home/support/context.hpp>
 #include <boost/spirit/home/support/info.hpp>
 #include <boost/spirit/home/support/attributes.hpp>
+#include <boost/spirit/home/support/nonterminal/extract_param.hpp>
 #include <boost/spirit/home/support/nonterminal/locals.hpp>
 #include <boost/spirit/home/qi/reference.hpp>
+#include <boost/spirit/home/qi/nonterminal/detail/parameterized.hpp>
 #include <boost/spirit/home/qi/nonterminal/detail/parser_binder.hpp>
 
 namespace boost { namespace spirit { namespace qi
@@ -55,35 +55,6 @@
     using spirit::info;
     using spirit::locals;
 
- template <typename Rule, typename Params>
- struct parameterized_rule : parser<parameterized_rule<Rule, Params> >
- {
- parameterized_rule(Rule const& rule, Params const& params)
- : ref(rule), params(params) {}
-
- template <typename Context, typename Iterator>
- struct attribute : Rule::template attribute<Context, Iterator> {};
-
- template <typename Iterator, typename Context
- , typename Skipper, typename Attribute>
- bool parse(Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Attribute& attr) const
- {
- // We pass the additional params argument to parse
- return ref.get().parse(first, last, context, skipper, attr, params);
- }
-
- template <typename Context>
- info what(Context& context) const
- {
- return ref.get().what(context);
- }
-
- boost::reference_wrapper<Rule const> ref;
- Params params;
- };
-
     template <
         typename Iterator
       , typename T1 = unused_type
@@ -107,57 +78,33 @@
         typedef mpl::vector<T1, T2, T3> template_params;
 
         // locals_type is a sequence of types to be used as local variables
- typedef typename fusion::result_of::as_vector<
- typename detail::extract_param<
- template_params
- , spirit::detail::is_locals<mpl::_>
- , locals<>
- >::type
- >::type
+ typedef typename
+ spirit::detail::extract_locals<template_params>::type
         locals_type;
 
         // The skip-parser type
         typedef typename
- result_of::compile<
- qi::domain
- , typename detail::extract_param<
- template_params
- , traits::matches<qi::domain, mpl::_>
- , unused_type
- >::type
- >::type
+ spirit::detail::extract_component<
+ qi::domain, template_params>::type
         skipper_type;
 
         typedef typename
- detail::extract_param<
- template_params
- , function_types::is_function<mpl::_>
- , void()
- >::type
+ spirit::detail::extract_sig<template_params>::type
         sig_type;
 
- typedef typename function_types::result_type<sig_type>::type attr_type_;
-
         // This is the rule's attribute type
         typedef typename
- mpl::if_<
- is_same<attr_type_, void>
- , unused_type
- , attr_type_
- >::type
+ spirit::detail::attr_from_sig<sig_type>::type
         attr_type;
         typedef typename add_reference<attr_type>::type attr_reference_type;
 
         // parameter_types is a sequence of types passed as parameters to the rule
         typedef typename
- function_types::parameter_types<sig_type>::type
- params_;
-
- typedef typename
- fusion::result_of::as_list<params_>::type
+ spirit::detail::params_from_sig<sig_type>::type
         parameter_types;
 
- static size_t const params_size = mpl::size<params_>::value;
+ static size_t const params_size =
+ fusion::result_of::size<parameter_types>::type::value;
 
         typedef context<
             fusion::cons<attr_reference_type, parameter_types>
@@ -268,6 +215,10 @@
                 typedef traits::make_attribute<attr_type, Attribute> make_attribute;
 
                 typename make_attribute::type attr_ = make_attribute::call(attr);
+
+ // If you are seeing a compilation error here, you are probably
+ // trying to use a rule or a grammar which has inherited
+ // attributes, without passing values for them.
                 context_type context(attr_);
 
                 // If you are seeing a compilation error here stating that the
@@ -293,6 +244,10 @@
                 typedef traits::make_attribute<attr_type, Attribute> make_attribute;
 
                 typename make_attribute::type attr_ = make_attribute::call(attr);
+
+ // If you are seeing a compilation error here, you are probably
+ // trying to use a rule or a grammar which has inherited
+ // attributes, passing values of incompatible types for them.
                 context_type context(attr_, params, caller_context);
 
                 // If you are seeing a compilation error here stating that the
@@ -325,8 +280,8 @@
         }
 
         // bring in the operator() overloads
- rule const& get_rule() const { return *this; }
- typedef this_type rule_type;
+ rule const& get_parameterized_subject() const { return *this; }
+ typedef rule parameterized_subject_type;
         #include <boost/spirit/home/qi/nonterminal/detail/fcall.hpp>
 
         std::string name_;

Added: trunk/boost/spirit/home/support/nonterminal/extract_param.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/nonterminal/extract_param.hpp 2009-08-12 09:06:44 EDT (Wed, 12 Aug 2009)
@@ -0,0 +1,121 @@
+/*=============================================================================
+ Copyright (c) 2001-2009 Joel de Guzman
+ Copyright (c) 2001-2009 Hartmut Kaiser
+ Copyright (c) 2009 Francois Barel
+
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_SPIRIT_EXTRACT_PARAM_AUGUST_08_2009_0848AM)
+#define BOOST_SPIRIT_EXTRACT_PARAM_AUGUST_08_2009_0848AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/support/meta_compiler.hpp>
+#include <boost/spirit/home/support/nonterminal/locals.hpp>
+#include <boost/spirit/home/support/unused.hpp>
+
+#include <boost/function_types/is_function.hpp>
+#include <boost/function_types/parameter_types.hpp>
+#include <boost/function_types/result_type.hpp>
+#include <boost/fusion/include/as_list.hpp>
+#include <boost/fusion/include/as_vector.hpp>
+#include <boost/mpl/deref.hpp>
+#include <boost/mpl/end.hpp>
+#include <boost/mpl/eval_if.hpp>
+#include <boost/mpl/find_if.hpp>
+#include <boost/mpl/identity.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/placeholders.hpp>
+#include <boost/type_traits/is_same.hpp>
+
+namespace boost { namespace spirit { namespace detail
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // Helpers to extract params (locals, attributes, ...) from nonterminal
+ // template arguments
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Types, typename Pred, typename Default>
+ struct extract_param
+ {
+ typedef typename mpl::find_if<Types, Pred>::type pos;
+
+ typedef typename
+ mpl::eval_if<
+ is_same<pos, typename mpl::end<Types>::type>
+ , mpl::identity<Default>
+ , mpl::deref<pos>
+ >::type
+ type;
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Types>
+ struct extract_locals
+ {
+ typedef
+ typename fusion::result_of::as_vector<
+ typename extract_param<
+ Types
+ , is_locals<mpl::_>
+ , locals<>
+ >::type
+ >::type
+ type;
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Domain, typename Types>
+ struct extract_component
+ {
+ typedef
+ typename spirit::result_of::compile<
+ Domain
+ , typename extract_param<
+ Types
+ , traits::matches<Domain, mpl::_>
+ , unused_type
+ >::type
+ >::type
+ type;
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Types>
+ struct extract_sig
+ {
+ typedef
+ typename extract_param<
+ Types
+ , function_types::is_function<mpl::_>
+ , void()
+ >::type
+ type;
+ };
+
+ template <typename Sig>
+ struct attr_from_sig
+ {
+ typedef typename function_types::result_type<Sig>::type attr;
+
+ typedef typename
+ mpl::if_<
+ is_same<attr, void>
+ , unused_type
+ , attr
+ >::type
+ type;
+ };
+
+ template <typename Sig>
+ struct params_from_sig
+ {
+ typedef typename function_types::parameter_types<Sig>::type params;
+
+ typedef typename fusion::result_of::as_list<params>::type type;
+ };
+}}}
+
+#endif


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