$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r55583 - in trunk: boost/spirit/home/support/nonterminal boost/spirit/repository/home boost/spirit/repository/home/karma boost/spirit/repository/home/karma/nonterminal boost/spirit/repository/home/qi/nonterminal boost/spirit/repository/home/support boost/spirit/repository/include libs/spirit/example/karma libs/spirit/repository/doc libs/spirit/repository/doc/html libs/spirit/repository/doc/html/spirit_repository libs/spirit/repository/doc/html/spirit_repository/karma_components libs/spirit/repository/doc/html/spirit_repository/karma_components/directives libs/spirit/repository/doc/html/spirit_repository/karma_components/nonterminal libs/spirit/repository/doc/html/spirit_repository/qi_components/directives libs/spirit/repository/doc/html/spirit_repository/qi_components/nonterminal libs/spirit/repository/doc/html/spirit_repository/qi_components/primitive libs/spirit/repository/doc/karma libs/spirit/repository/doc/qi libs/spirit/repository/example/karma libs/spirit/repository/example/qi libs/spirit/repository/test libs/spirit/repository/test/karma libs/spirit/repository/test/qi
From: frabar666_at_[hidden]
Date: 2009-08-14 12:39:59
Author: fbarel
Date: 2009-08-14 12:39:56 EDT (Fri, 14 Aug 2009)
New Revision: 55583
URL: http://svn.boost.org/trac/boost/changeset/55583
Log:
Spirit: adding Karma subrules to repository
Added:
   trunk/boost/spirit/repository/home/karma/nonterminal/
   trunk/boost/spirit/repository/home/karma/nonterminal.hpp   (contents, props changed)
   trunk/boost/spirit/repository/home/karma/nonterminal/subrule.hpp   (contents, props changed)
   trunk/boost/spirit/repository/home/support/subrule_context.hpp   (contents, props changed)
   trunk/boost/spirit/repository/include/karma_nonterminal.hpp   (contents, props changed)
   trunk/boost/spirit/repository/include/karma_subrule.hpp   (contents, props changed)
   trunk/libs/spirit/repository/doc/html/spirit_repository/karma_components/nonterminal/
   trunk/libs/spirit/repository/doc/html/spirit_repository/karma_components/nonterminal.html   (contents, props changed)
   trunk/libs/spirit/repository/doc/html/spirit_repository/karma_components/nonterminal/subrule.html   (contents, props changed)
   trunk/libs/spirit/repository/doc/karma/nonterminals.qbk   (contents, props changed)
   trunk/libs/spirit/repository/doc/karma/subrule.qbk   (contents, props changed)
   trunk/libs/spirit/repository/example/karma/calc2_ast.hpp
      - copied unchanged from r55581, /trunk/libs/spirit/example/karma/calc2_ast.hpp
   trunk/libs/spirit/repository/example/karma/calc2_ast_dump_sr.cpp   (contents, props changed)
   trunk/libs/spirit/repository/example/karma/mini_xml_karma_sr.cpp   (contents, props changed)
   trunk/libs/spirit/repository/test/karma/subrule.cpp   (contents, props changed)
Text files modified: 
   trunk/boost/spirit/home/support/nonterminal/extract_param.hpp                                                   |    51 +++++++++++++++----------------------   
   trunk/boost/spirit/repository/home/karma.hpp                                                                    |     1                                         
   trunk/boost/spirit/repository/home/qi/nonterminal/subrule.hpp                                                   |    44 +++------------------------------       
   trunk/libs/spirit/example/karma/mini_xml_karma.cpp                                                              |    10 ++++---                                 
   trunk/libs/spirit/repository/doc/html/index.html                                                                |     8 ++++-                                   
   trunk/libs/spirit/repository/doc/html/spirit_repository/karma_components.html                                   |     4 +++                                     
   trunk/libs/spirit/repository/doc/html/spirit_repository/karma_components/directives/karma_confix_generator.html |    23 +++++++++--------                       
   trunk/libs/spirit/repository/doc/html/spirit_repository/preface.html                                            |     8 +++---                                  
   trunk/libs/spirit/repository/doc/html/spirit_repository/qi_components/directives/confix.html                    |    18 ++++++------                            
   trunk/libs/spirit/repository/doc/html/spirit_repository/qi_components/directives/distinct.html                  |    16 ++++++------                            
   trunk/libs/spirit/repository/doc/html/spirit_repository/qi_components/nonterminal/subrule.html                  |    53 ++++++++++++++++++++++++++++++--------- 
   trunk/libs/spirit/repository/doc/html/spirit_repository/qi_components/primitive/flush_multi_pass.html           |    16 ++++++------                            
   trunk/libs/spirit/repository/doc/karma.qbk                                                                      |     2                                         
   trunk/libs/spirit/repository/doc/qi/subrule.qbk                                                                 |    19 +++++++------                           
   trunk/libs/spirit/repository/example/karma/Jamfile                                                              |     2 +                                       
   trunk/libs/spirit/repository/example/qi/calc1_sr.cpp                                                            |     2                                         
   trunk/libs/spirit/repository/test/CMakeLists.txt                                                                |     1                                         
   trunk/libs/spirit/repository/test/Jamfile                                                                       |     1                                         
   trunk/libs/spirit/repository/test/qi/subrule.cpp                                                                |    10 +++++++                                 
   19 files changed, 149 insertions(+), 140 deletions(-)
Modified: trunk/boost/spirit/home/support/nonterminal/extract_param.hpp
==============================================================================
--- trunk/boost/spirit/home/support/nonterminal/extract_param.hpp	(original)
+++ trunk/boost/spirit/home/support/nonterminal/extract_param.hpp	2009-08-14 12:39:56 EDT (Fri, 14 Aug 2009)
@@ -54,46 +54,37 @@
     ///////////////////////////////////////////////////////////////////////////
     template <typename Types>
     struct extract_locals
-    {
-        typedef
-            typename fusion::result_of::as_vector<
-                typename extract_param<
-                    Types
-                  , is_locals<mpl::_>
-                  , locals<>
-                >::type
+      : fusion::result_of::as_vector<
+            typename extract_param<
+                Types
+              , is_locals<mpl::_>
+              , locals<>
             >::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
+      : spirit::result_of::compile<
+            Domain
+          , typename extract_param<
+                Types
+              , traits::matches<Domain, mpl::_>
+              , unused_type
             >::type
-        type;
-    };
+        >
+    {};
 
     ///////////////////////////////////////////////////////////////////////////
     template <typename Types>
     struct extract_sig
-    {
-        typedef
-            typename extract_param<
-                Types
-              , function_types::is_function<mpl::_>
-              , void()
-            >::type
-        type;
-    };
+      : extract_param<
+            Types
+          , function_types::is_function<mpl::_>
+          , void()
+        >
+    {};
 
     template <typename Sig>
     struct attr_from_sig
Modified: trunk/boost/spirit/repository/home/karma.hpp
==============================================================================
--- trunk/boost/spirit/repository/home/karma.hpp	(original)
+++ trunk/boost/spirit/repository/home/karma.hpp	2009-08-14 12:39:56 EDT (Fri, 14 Aug 2009)
@@ -12,6 +12,7 @@
 #endif
 
 #include <boost/spirit/repository/home/karma/directive.hpp>
+#include <boost/spirit/repository/home/karma/nonterminal.hpp>
 
 #endif
 
Added: trunk/boost/spirit/repository/home/karma/nonterminal.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/repository/home/karma/nonterminal.hpp	2009-08-14 12:39:56 EDT (Fri, 14 Aug 2009)
@@ -0,0 +1,18 @@
+//  Copyright (c) 2001-2009 Hartmut Kaiser
+//  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(SPIRIT_REPOSITORY_KARMA_NONTERMINAL_AUG_12_2009_0807PM)
+#define SPIRIT_REPOSITORY_KARMA_NONTERMINAL_AUG_12_2009_0807PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/repository/home/karma/nonterminal/subrule.hpp>
+
+#endif
+
Added: trunk/boost/spirit/repository/home/karma/nonterminal/subrule.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/repository/home/karma/nonterminal/subrule.hpp	2009-08-14 12:39:56 EDT (Fri, 14 Aug 2009)
@@ -0,0 +1,705 @@
+//  Copyright (c) 2009 Francois Barel
+//  Copyright (c) 2001-2009 Joel de Guzman
+//  Copyright (c) 2001-2009 Hartmut Kaiser
+//
+//  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_REPOSITORY_KARMA_SUBRULE_AUGUST_12_2009_0813PM)
+#define BOOST_SPIRIT_REPOSITORY_KARMA_SUBRULE_AUGUST_12_2009_0813PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/karma/domain.hpp>
+#include <boost/spirit/home/karma/meta_compiler.hpp>
+#include <boost/spirit/home/karma/generator.hpp>
+#include <boost/spirit/home/karma/reference.hpp>
+#include <boost/spirit/home/karma/nonterminal/detail/generator_binder.hpp>
+#include <boost/spirit/home/karma/nonterminal/detail/parameterized.hpp>
+#include <boost/spirit/home/support/argument.hpp>
+#include <boost/spirit/home/support/assert_msg.hpp>
+#include <boost/spirit/home/support/attributes.hpp>
+#include <boost/spirit/home/support/info.hpp>
+#include <boost/spirit/home/support/unused.hpp>
+#include <boost/spirit/home/support/nonterminal/extract_param.hpp>
+#include <boost/spirit/home/support/nonterminal/locals.hpp>
+#include <boost/spirit/repository/home/support/subrule_context.hpp>
+
+#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>
+#include <boost/fusion/include/make_map.hpp>
+#include <boost/fusion/include/make_vector.hpp>
+#include <boost/fusion/include/size.hpp>
+#include <boost/fusion/include/vector.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/identity.hpp>
+#include <boost/mpl/int.hpp>
+#include <boost/mpl/vector.hpp>
+#include <boost/type_traits/add_reference.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+
+#if defined(BOOST_MSVC)
+# pragma warning(push)
+# pragma warning(disable: 4355) // 'this' : used in base member initializer list warning
+#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
+{
+    ///////////////////////////////////////////////////////////////////////////
+    // subrule_group:
+    // - generator representing a group of subrule definitions (one or more),
+    //   invokes first subrule on entry,
+    // - also a Proto terminal, so that a group behaves like any Spirit
+    //   expression.
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Defs>
+    struct subrule_group
+      : proto::extends<
+            typename proto::terminal<
+                spirit::karma::reference<subrule_group<Defs> const>
+            >::type
+          , subrule_group<Defs>
+        >
+      , spirit::karma::generator<subrule_group<Defs> >
+    {
+        struct properties
+            // Forward to first subrule.
+          : remove_reference<
+                typename fusion::result_of::front<Defs>::type
+            >::type::second_type::subject_type::properties {};
+
+        // Fusion associative sequence, associating each subrule ID in this
+        // group (as an MPL integral constant) with its definition
+        typedef Defs defs_type;
+
+        typedef subrule_group<Defs> this_type;
+        typedef spirit::karma::reference<this_type const> reference_;
+        typedef typename proto::terminal<reference_>::type terminal;
+        typedef proto::extends<terminal, this_type> base_type;
+
+        static size_t const params_size =
+            // Forward to first subrule.
+            remove_reference<
+                typename fusion::result_of::front<Defs>::type
+            >::type::second_type::params_size;
+
+        subrule_group(subrule_group const& rhs)
+          : base_type(terminal::make(reference_(*this)))
+          , defs(rhs.defs)
+        {
+        }
+
+        subrule_group(Defs const& defs)
+          : base_type(terminal::make(reference_(*this)))
+          , defs(defs)
+        {
+        }
+
+        // from a subrule ID, get the type of a reference to its definition
+        template <int ID>
+        struct def_type
+        {
+            typedef mpl::int_<ID> id_type;
+
+            // If you are seeing a compilation error here, you are trying
+            // to use a subrule which was not defined in this group.
+            BOOST_SPIRIT_ASSERT_MSG(
+                (fusion::result_of::has_key<
+                    defs_type const, id_type>::type::value)
+              , subrule_used_without_being_defined, (mpl::int_<ID>));
+
+            typedef typename
+                fusion::result_of::at_key<defs_type const, id_type>::type
+            type;
+        };
+
+        // from a subrule ID, get a reference to its definition
+        template <int ID>
+        typename def_type<ID>::type def() const
+        {
+            return fusion::at_key<mpl::int_<ID> >(defs);
+        }
+
+        template <typename Context, typename Iterator>
+        struct attribute
+            // Forward to first subrule.
+          : mpl::identity<
+                typename remove_reference<
+                    typename fusion::result_of::front<Defs>::type
+                >::type::second_type::attr_type> {};
+
+        template <typename OutputIterator, typename Context
+          , typename Delimiter, typename Attribute>
+        bool generate(OutputIterator& sink, Context& context
+          , Delimiter const& delimiter, Attribute const& attr) const
+        {
+            // Forward to first subrule.
+            return generate_subrule(fusion::front(defs).second
+              , sink, context, delimiter, attr);
+        }
+
+        template <typename OutputIterator, typename Context
+          , typename Delimiter, typename Attribute
+          , typename Params>
+        bool generate(OutputIterator& sink, Context& context
+          , Delimiter const& delimiter, Attribute const& attr
+          , Params const& params) const
+        {
+            // Forward to first subrule.
+            return generate_subrule(fusion::front(defs).second
+              , sink, context, delimiter, attr, params);
+        }
+
+        template <int ID, typename OutputIterator, typename Context
+          , typename Delimiter, typename Attribute>
+        bool generate_subrule_id(OutputIterator& sink
+          , Context& context, Delimiter const& delimiter
+          , Attribute const& attr) const
+        {
+            return generate_subrule(def<ID>()
+              , sink, context, delimiter, attr);
+        }
+
+        template <int ID, typename OutputIterator, typename Context
+          , typename Delimiter, typename Attribute, typename Params>
+        bool generate_subrule_id(OutputIterator& sink
+          , Context& context, Delimiter const& delimiter
+          , Attribute const& attr, Params const& params) const
+        {
+            return generate_subrule(def<ID>()
+              , sink, context, delimiter, attr, params);
+        }
+
+        template <typename Def, typename OutputIterator, typename Context
+          , typename Delimiter, typename Attribute>
+        bool generate_subrule(Def const& def, OutputIterator& sink
+          , Context& /*caller_context*/, Delimiter const& delimiter
+          , Attribute const& attr) const
+        {
+            // compute context type for this subrule
+            typedef typename Def::locals_type subrule_locals_type;
+            typedef typename Def::delimiter_type subrule_delimiter_type;
+            typedef typename Def::attr_type subrule_attr_type;
+            typedef typename Def::attr_reference_type subrule_attr_reference_type;
+            typedef typename Def::parameter_types subrule_parameter_types;
+
+            typedef
+                subrule_context<
+                    this_type
+                  , fusion::cons<
+                        subrule_attr_reference_type, subrule_parameter_types>
+                  , subrule_locals_type
+                >
+            context_type;
+
+            // Create an attribute if none is supplied.
+            typedef traits::make_attribute<subrule_attr_type, Attribute>
+                make_attribute;
+
+            // If you are seeing a compilation error here, you are probably
+            // trying to use a subrule which has inherited attributes,
+            // without passing values for them.
+            context_type context(*this, make_attribute::call(attr));
+
+            // If you are seeing a compilation error here stating that the
+            // forth parameter can't be converted to a karma::reference
+            // then you are probably trying to use a subrule with an
+            // incompatible delimiter type.
+            return call_binder<subrule_delimiter_type>(
+                sink, context, delimiter, def.binder);
+        }
+
+        template <typename Def, typename OutputIterator, typename Context
+          , typename Delimiter, typename Attribute, typename Params>
+        bool generate_subrule(Def const& def, OutputIterator& sink
+          , Context& caller_context, Delimiter const& delimiter
+          , Attribute const& attr, Params const& params) const
+        {
+            // compute context type for this subrule
+            typedef typename Def::locals_type subrule_locals_type;
+            typedef typename Def::delimiter_type subrule_delimiter_type;
+            typedef typename Def::attr_type subrule_attr_type;
+            typedef typename Def::attr_reference_type subrule_attr_reference_type;
+            typedef typename Def::parameter_types subrule_parameter_types;
+
+            typedef
+                subrule_context<
+                    this_type
+                  , fusion::cons<
+                        subrule_attr_reference_type, subrule_parameter_types>
+                  , subrule_locals_type
+                >
+            context_type;
+
+            // Create an attribute if none is supplied.
+            typedef traits::make_attribute<subrule_attr_type, Attribute>
+                make_attribute;
+
+            // If you are seeing a compilation error here, you are probably
+            // trying to use a subrule which has inherited attributes,
+            // passing values of incompatible types for them.
+            context_type context(*this, make_attribute::call(attr)
+              , params, caller_context);
+
+            // If you are seeing a compilation error here stating that the
+            // forth parameter can't be converted to a karma::reference
+            // then you are probably trying to use a subrule with an
+            // incompatible delimiter type.
+            return call_binder<subrule_delimiter_type>(
+                sink, context, delimiter, def.binder);
+        }
+
+        // wrapper to let the incoming delimiter be converted to the
+        // delimiter type expected by the subrule being invoked
+        template <typename Delimiter, typename OutputIterator
+          , typename Context, typename Binder>
+        bool call_binder(OutputIterator& sink, Context& context
+          , Delimiter const& delimiter, Binder const& binder) const
+        {
+            return binder(sink, context, delimiter);
+        }
+
+        template <typename Context>
+        info what(Context& context) const
+        {
+            // Forward to first subrule.
+            return fusion::front(defs).second.binder.g.what(context);
+        }
+
+        // bring in the operator() overloads
+        this_type const& get_parameterized_subject() const { return *this; }
+        typedef this_type parameterized_subject_type;
+        #include <boost/spirit/home/karma/nonterminal/detail/fcall.hpp>
+
+        Defs defs;
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    // subrule_definition: holds one particular definition of a subrule
+    ///////////////////////////////////////////////////////////////////////////
+    template <
+        int ID_
+      , typename Locals
+      , typename Delimiter
+      , typename Attr
+      , typename AttrRef
+      , typename Parameters
+      , size_t ParamsSize
+      , typename Subject
+      , bool Auto_
+    >
+    struct subrule_definition
+    {
+        typedef mpl::int_<ID_> id_type;
+        BOOST_STATIC_CONSTANT(int, ID = ID_);
+
+        typedef Locals locals_type;
+        typedef Delimiter delimiter_type;
+        typedef Attr attr_type;
+        typedef AttrRef attr_reference_type;
+        typedef Parameters parameter_types;
+        static size_t const params_size = ParamsSize;
+
+        typedef Subject subject_type;
+        typedef mpl::bool_<Auto_> auto_type;
+        BOOST_STATIC_CONSTANT(bool, Auto = Auto_);
+
+        typedef spirit::karma::detail::generator_binder<
+            Subject, auto_type> binder_type;
+
+        subrule_definition(Subject const& subject, std::string const& name)
+          : binder(subject), name(name)
+        {
+        }
+
+        binder_type const binder;
+        std::string const name;
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    // subrule placeholder:
+    // - on subrule definition: helper for creation of subrule_group,
+    // - on subrule invocation: Proto terminal and generator.
+    ///////////////////////////////////////////////////////////////////////////
+    template <
+        int ID_
+      , typename T1 = unused_type
+      , typename T2 = unused_type
+      , typename T3 = unused_type
+    >
+    struct subrule
+      : proto::extends<
+            typename proto::terminal<
+                spirit::karma::reference<subrule<ID_, T1, T2, T3> const>
+            >::type
+          , subrule<ID_, T1, T2, T3>
+        >
+      , spirit::karma::generator<subrule<ID_, T1, T2, T3> >
+    {
+        //FIXME should go fetch the real properties of this subrule's definition in the current context, but we don't
+        // have the context here (properties would need to be 'template<typename Context> struct properties' instead)
+        typedef mpl::int_<
+            spirit::karma::generator_properties::all_properties> properties;
+
+        typedef mpl::int_<ID_> id_type;
+        BOOST_STATIC_CONSTANT(int, ID = ID_);
+
+        typedef subrule<ID_, T1, T2, T3> this_type;
+        typedef spirit::karma::reference<this_type const> reference_;
+        typedef typename proto::terminal<reference_>::type terminal;
+        typedef proto::extends<terminal, this_type> base_type;
+
+        typedef mpl::vector<T1, T2, T3> template_params;
+
+        // locals_type is a sequence of types to be used as local variables
+        typedef typename
+            spirit::detail::extract_locals<template_params>::type
+        locals_type;
+
+        // The delimiter-generator type
+        typedef typename
+            spirit::detail::extract_component<
+                spirit::karma::domain, template_params>::type
+        delimiter_type;
+
+        typedef typename
+            spirit::detail::extract_sig<template_params>::type
+        sig_type;
+
+        // This is the subrule's attribute type
+        typedef typename
+            spirit::detail::attr_from_sig<sig_type>::type
+        attr_type;
+        typedef typename add_reference<
+            typename add_const<attr_type>::type>::type attr_reference_type;
+
+        // parameter_types is a sequence of types passed as parameters to the subrule
+        typedef typename
+            spirit::detail::params_from_sig<sig_type>::type
+        parameter_types;
+
+        static size_t const params_size =
+            fusion::result_of::size<parameter_types>::type::value;
+
+        explicit subrule(std::string const& name_ = "unnamed-subrule")
+          : base_type(terminal::make(reference_(*this)))
+          , name_(name_)
+        {
+        }
+
+        // compute type of this subrule's definition for expr type Expr
+        template <typename Expr, bool Auto>
+        struct def_type_helper
+        {
+            // Report invalid expression error as early as possible.
+            // If you got an error_invalid_expression error message here,
+            // then the expression (Expr) is not a valid spirit karma expression.
+            BOOST_SPIRIT_ASSERT_MATCH(spirit::karma::domain, Expr);
+
+            typedef typename result_of::compile<
+                spirit::karma::domain, Expr>::type subject_type;
+
+            typedef subrule_definition<
+                ID_
+              , locals_type
+              , delimiter_type
+              , attr_type
+              , attr_reference_type
+              , parameter_types
+              , params_size
+              , subject_type
+              , Auto
+            > const type;
+        };
+
+        // compute type of subrule group containing only this
+        // subrule's definition for expr type Expr
+        template <typename Expr, bool Auto>
+        struct group_type_helper
+        {
+            typedef typename def_type_helper<Expr, Auto>::type def_type;
+
+            // create Defs map with only one entry: (ID -> def)
+            typedef typename
+                fusion::result_of::make_map<id_type, def_type>::type
+            defs_type;
+
+            typedef subrule_group<defs_type> type;
+        };
+
+        template <typename Expr>
+        typename group_type_helper<Expr, false>::type
+        operator=(Expr const& expr) const
+        {
+            typedef group_type_helper<Expr, false> helper;
+            typedef typename helper::def_type def_type;
+            typedef typename helper::type result_type;
+            return result_type(fusion::make_map<id_type>(
+                def_type(compile<spirit::karma::domain>(expr), name_)));
+        }
+
+        template <typename Expr>
+        friend typename group_type_helper<Expr, true>::type
+        operator%=(subrule const& sr, Expr const& expr)
+        {
+            typedef group_type_helper<Expr, true> helper;
+            typedef typename helper::def_type def_type;
+            typedef typename helper::type result_type;
+            return result_type(fusion::make_map<id_type>(
+                def_type(compile<spirit::karma::domain>(expr), sr.name_)));
+        }
+
+        // non-const versions needed to suppress proto's %= kicking in
+        template <typename Expr>
+        friend typename group_type_helper<Expr, true>::type
+        operator%=(subrule const& sr, Expr& expr)
+        {
+            return operator%=(
+                sr
+              , static_cast<Expr const&>(expr));
+        }
+        template <typename Expr>
+        friend typename group_type_helper<Expr, true>::type
+        operator%=(subrule& sr, Expr const& expr)
+        {
+            return operator%=(
+                static_cast<subrule const&>(sr)
+              , expr);
+        }
+        template <typename Expr>
+        friend typename group_type_helper<Expr, true>::type
+        operator%=(subrule& sr, Expr& expr)
+        {
+            return operator%=(
+                static_cast<subrule const&>(sr)
+              , static_cast<Expr const&>(expr));
+        }
+
+        std::string const& name() const
+        {
+            return name_;
+        }
+
+        void name(std::string const& str)
+        {
+            name_ = str;
+        }
+
+        template <typename Context, typename Iterator>
+        struct attribute
+        {
+            typedef attr_type type;
+        };
+
+        template <typename OutputIterator, typename Group
+          , typename Attributes, typename Locals
+          , typename Delimiter, typename Attribute>
+        bool generate(OutputIterator& sink
+          , subrule_context<Group, Attributes, Locals>& context
+          , Delimiter const& delimiter, Attribute const& attr) const
+        {
+            return context.group.template generate_subrule_id<ID_>(
+                sink, context, delimiter, attr);
+        }
+
+        template <typename OutputIterator, typename Context
+          , typename Delimiter, typename Attribute>
+        bool generate(OutputIterator& /*sink*/
+          , Context& /*context*/
+          , Delimiter const& /*delimiter*/, Attribute const& /*attr*/) const
+        {
+            // If you are seeing a compilation error here, you are trying
+            // to use a subrule as a generator outside of a subrule group.
+            BOOST_SPIRIT_ASSERT_MSG(false
+              , subrule_used_outside_subrule_group, (id_type));
+
+            return false;
+        }
+
+        template <typename OutputIterator, typename Group
+          , typename Attributes, typename Locals
+          , typename Delimiter, typename Attribute
+          , typename Params>
+        bool generate(OutputIterator& sink
+          , subrule_context<Group, Attributes, Locals>& context
+          , Delimiter const& delimiter, Attribute const& attr
+          , Params const& params) const
+        {
+            return context.group.template generate_subrule_id<ID_>(
+                sink, context, delimiter, attr, params);
+        }
+
+        template <typename OutputIterator, typename Context
+          , typename Delimiter, typename Attribute
+          , typename Params>
+        bool generate(OutputIterator& /*sink*/
+          , Context& /*context*/
+          , Delimiter const& /*delimiter*/, Attribute const& /*attr*/
+          , Params const& /*params*/) const
+        {
+            // If you are seeing a compilation error here, you are trying
+            // to use a subrule as a generator outside of a subrule group.
+            BOOST_SPIRIT_ASSERT_MSG(false
+              , subrule_used_outside_subrule_group, (id_type));
+
+            return false;
+        }
+
+        template <typename Context>
+        info what(Context& /*context*/) const
+        {
+            return info(name_);
+        }
+
+        // bring in the operator() overloads
+        this_type const& get_parameterized_subject() const { return *this; }
+        typedef this_type parameterized_subject_type;
+        #include <boost/spirit/home/karma/nonterminal/detail/fcall.hpp>
+
+        std::string name_;
+    };
+}}}}
+
+///////////////////////////////////////////////////////////////////////////////
+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
+
+#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-14 12:39:56 EDT (Fri, 14 Aug 2009)
@@ -5,8 +5,8 @@
     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(SPIRIT_REPOSITORY_QI_SUBRULE_AUGUST_06_2009_0239AM)
-#define SPIRIT_REPOSITORY_QI_SUBRULE_AUGUST_06_2009_0239AM
+#if !defined(BOOST_SPIRIT_REPOSITORY_QI_SUBRULE_AUGUST_06_2009_0239AM)
+#define BOOST_SPIRIT_REPOSITORY_QI_SUBRULE_AUGUST_06_2009_0239AM
 
 #if defined(_MSC_VER)
 #pragma once
@@ -21,11 +21,11 @@
 #include <boost/spirit/home/support/argument.hpp>
 #include <boost/spirit/home/support/assert_msg.hpp>
 #include <boost/spirit/home/support/attributes.hpp>
-#include <boost/spirit/home/support/context.hpp>
 #include <boost/spirit/home/support/info.hpp>
 #include <boost/spirit/home/support/unused.hpp>
 #include <boost/spirit/home/support/nonterminal/extract_param.hpp>
 #include <boost/spirit/home/support/nonterminal/locals.hpp>
+#include <boost/spirit/repository/home/support/subrule_context.hpp>
 
 #include <boost/fusion/include/as_map.hpp>
 #include <boost/fusion/include/at_key.hpp>
@@ -72,42 +72,6 @@
 namespace boost { namespace spirit { namespace repository { namespace qi
 {
     ///////////////////////////////////////////////////////////////////////////
-    // subrule_context: special context used when parsing subrules, to pass
-    // around the current set of subrule definitions (subrule_group)
-    ///////////////////////////////////////////////////////////////////////////
-    template <typename Group, typename Attributes, typename Locals>
-    struct subrule_context
-      : context<Attributes, Locals>
-    {
-        typedef context<Attributes, Locals> base_type;
-        typedef Group group_type;
-
-        subrule_context(
-            Group const& group
-          , typename Attributes::car_type attribute
-        ) : base_type(attribute), group(group)
-        {
-        }
-
-        template <typename Args, typename Context>
-        subrule_context(
-            Group const& group
-          , typename Attributes::car_type attribute
-          , Args const& args
-          , Context& caller_context
-        ) : base_type(attribute, args, caller_context), group(group)
-        {
-        }
-
-        subrule_context(Group const& group, Attributes const& attributes)
-          : base_type(attributes), group(group)
-        {
-        }
-
-        Group const& group;
-    };
-
-    ///////////////////////////////////////////////////////////////////////////
     // subrule_group:
     // - parser representing a group of subrule definitions (one or more),
     //   invokes first subrule on entry,
@@ -339,7 +303,7 @@
     };
 
     ///////////////////////////////////////////////////////////////////////////
-    // subrule_definition: holds one definition of a subrule
+    // subrule_definition: holds one particular definition of a subrule
     ///////////////////////////////////////////////////////////////////////////
     template <
         int ID_
Added: trunk/boost/spirit/repository/home/support/subrule_context.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/repository/home/support/subrule_context.hpp	2009-08-14 12:39:56 EDT (Fri, 14 Aug 2009)
@@ -0,0 +1,57 @@
+/*=============================================================================
+    Copyright (c) 2009 Francois Barel
+    Copyright (c) 2001-2009 Joel de Guzman
+
+    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_REPOSITORY_SUPPORT_SUBRULE_CONTEXT_AUGUST_12_2009_0539PM)
+#define BOOST_SPIRIT_REPOSITORY_SUPPORT_SUBRULE_CONTEXT_AUGUST_12_2009_0539PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/support/context.hpp>
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit { namespace repository
+{
+    ///////////////////////////////////////////////////////////////////////////
+    // subrule_context: special context used with subrules, to pass around
+    // the current set of subrule definitions (subrule_group)
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Group, typename Attributes, typename Locals>
+    struct subrule_context
+      : context<Attributes, Locals>
+    {
+        typedef context<Attributes, Locals> base_type;
+        typedef Group group_type;
+
+        subrule_context(
+            Group const& group
+          , typename Attributes::car_type attribute
+        ) : base_type(attribute), group(group)
+        {
+        }
+
+        template <typename Args, typename Context>
+        subrule_context(
+            Group const& group
+          , typename Attributes::car_type attribute
+          , Args const& args
+          , Context& caller_context
+        ) : base_type(attribute, args, caller_context), group(group)
+        {
+        }
+
+        subrule_context(Group const& group, Attributes const& attributes)
+          : base_type(attributes), group(group)
+        {
+        }
+
+        Group const& group;
+    };
+}}}
+
+#endif
Added: trunk/boost/spirit/repository/include/karma_nonterminal.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/repository/include/karma_nonterminal.hpp	2009-08-14 12:39:56 EDT (Fri, 14 Aug 2009)
@@ -0,0 +1,19 @@
+/*=============================================================================
+    Copyright (c) 2001-2009 Joel de Guzman
+    Copyright (c) 2001-2009 Hartmut Kaiser
+    Copyright (c) 2009 Francois Barel
+    http://spirit.sourceforge.net/
+
+    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)
+=============================================================================*/
+#ifndef BOOST_SPIRIT_REPOSITORY_INCLUDE_KARMA_NONTERMINAL
+#define BOOST_SPIRIT_REPOSITORY_INCLUDE_KARMA_NONTERMINAL
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/repository/home/karma/nonterminal.hpp>
+
+#endif
Added: trunk/boost/spirit/repository/include/karma_subrule.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/repository/include/karma_subrule.hpp	2009-08-14 12:39:56 EDT (Fri, 14 Aug 2009)
@@ -0,0 +1,19 @@
+/*=============================================================================
+    Copyright (c) 2001-2009 Joel de Guzman
+    Copyright (c) 2001-2009 Hartmut Kaiser
+    Copyright (c) 2009 Francois Barel
+    http://spirit.sourceforge.net/
+
+    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)
+=============================================================================*/
+#ifndef BOOST_SPIRIT_REPOSITORY_INCLUDE_KARMA_SUBRULE
+#define BOOST_SPIRIT_REPOSITORY_INCLUDE_KARMA_SUBRULE
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/repository/home/karma/nonterminal/subrule.hpp>
+
+#endif
Modified: trunk/libs/spirit/example/karma/mini_xml_karma.cpp
==============================================================================
--- trunk/libs/spirit/example/karma/mini_xml_karma.cpp	(original)
+++ trunk/libs/spirit/example/karma/mini_xml_karma.cpp	2009-08-14 12:39:56 EDT (Fri, 14 Aug 2009)
@@ -80,6 +80,7 @@
 
         start_tag =
                 '<'
+            >>  !lit('/')
             >>  lexeme[+(char_ - '>')       [_val += _1]]
             >>  '>'
         ;
@@ -180,8 +181,8 @@
     mini_xml_parser xmlin;  //  Our grammar definition
     mini_xml ast; // our tree
 
-    std::string::iterator iter = storage.begin();
-    std::string::iterator end = storage.end();
+    std::string::const_iterator iter = storage.begin();
+    std::string::const_iterator end = storage.end();
     bool r = qi::phrase_parse(iter, end, xmlin, space, ast);
 
     if (r && iter == end)
@@ -205,8 +206,9 @@
     }
     else
     {
-        std::size_t dist = std::distance(storage.begin(), iter);
-        std::string::iterator some = 
+        std::string::const_iterator begin = storage.begin();
+        std::size_t dist = std::distance(begin, iter);
+        std::string::const_iterator some = 
             iter + (std::min)(storage.size()-dist, std::size_t(30));
         std::string context(iter, some);
         std::cout << "-------------------------\n";
Modified: trunk/libs/spirit/repository/doc/html/index.html
==============================================================================
--- trunk/libs/spirit/repository/doc/html/index.html	(original)
+++ trunk/libs/spirit/repository/doc/html/index.html	2009-08-14 12:39:56 EDT (Fri, 14 Aug 2009)
@@ -34,7 +34,7 @@
 <div><p class="copyright">Copyright © 2001-2009 Joel
       de Guzman, Hartmut Kaiser</p></div>
 <div><div class="legalnotice" title="Legal Notice">
-<a name="id2646821"></a><p>
+<a name="id3095674"></a><p>
         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)
       </p>
@@ -71,12 +71,16 @@
       Generator Directives</a></span></dt>
 <dd><dl><dt><span class="section"><a href="spirit_repository/karma_components/directives/karma_confix_generator.html">Karma
         Confix Generator</a></span></dt></dl></dd>
+<dt><span class="section"><a href="spirit_repository/karma_components/nonterminal.html"> Karma
+      Generator Non-terminals</a></span></dt>
+<dd><dl><dt><span class="section"><a href="spirit_repository/karma_components/nonterminal/subrule.html">
+        Karma subrules</a></span></dt></dl></dd>
 </dl></dd>
 </dl>
 </div>
 </div>
 <table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
-<td align="left"><p><small>Last revised: August 13, 2009 at 12:57:35 GMT</small></p></td>
+<td align="left"><p><small>Last revised: August 14, 2009 at 16:19:31 GMT</small></p></td>
 <td align="right"><div class="copyright-footer"></div></td>
 </tr></table>
 <hr>
Modified: trunk/libs/spirit/repository/doc/html/spirit_repository/karma_components.html
==============================================================================
--- trunk/libs/spirit/repository/doc/html/spirit_repository/karma_components.html	(original)
+++ trunk/libs/spirit/repository/doc/html/spirit_repository/karma_components.html	2009-08-14 12:39:56 EDT (Fri, 14 Aug 2009)
@@ -31,6 +31,10 @@
       Generator Directives</a></span></dt>
 <dd><dl><dt><span class="section"><a href="karma_components/directives/karma_confix_generator.html">Karma
         Confix Generator</a></span></dt></dl></dd>
+<dt><span class="section"><a href="karma_components/nonterminal.html"> Karma
+      Generator Non-terminals</a></span></dt>
+<dd><dl><dt><span class="section"><a href="karma_components/nonterminal/subrule.html">
+        Karma subrules</a></span></dt></dl></dd>
 </dl></div>
 </div>
 <table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
Modified: trunk/libs/spirit/repository/doc/html/spirit_repository/karma_components/directives/karma_confix_generator.html
==============================================================================
--- trunk/libs/spirit/repository/doc/html/spirit_repository/karma_components/directives/karma_confix_generator.html	(original)
+++ trunk/libs/spirit/repository/doc/html/spirit_repository/karma_components/directives/karma_confix_generator.html	2009-08-14 12:39:56 EDT (Fri, 14 Aug 2009)
@@ -7,6 +7,7 @@
 <link rel="home" href="../../../index.html" title="Spirit Repository 0.1">
 <link rel="up" href="../directives.html" title="Karma Generator Directives">
 <link rel="prev" href="../directives.html" title="Karma Generator Directives">
+<link rel="next" href="../nonterminal.html" title="Karma Generator Non-terminals">
 </head>
 <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
 <table cellpadding="2" width="100%"><tr>
@@ -19,7 +20,7 @@
 </tr></table>
 <hr>
 <div class="spirit-nav">
-<a accesskey="p" href="../directives.html"><img src="../../../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../directives.html"><img src="../../../../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../../../../../../doc/html/images/home.png" alt="Home"></a>
+<a accesskey="p" href="../directives.html"><img src="../../../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../directives.html"><img src="../../../../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="../nonterminal.html"><img src="../../../../../../../../doc/html/images/next.png" alt="Next"></a>
 </div>
 <div class="section" title="Karma Confix Generator">
 <div class="titlepage"><div><div><h4 class="title">
@@ -27,7 +28,7 @@
         Confix Generator</a>
 </h4></div></div></div>
 <a name="spirit_repository.karma_components.directives.karma_confix_generator.description"></a><h6>
-<a name="id2706694"></a>
+<a name="id3155583"></a>
           <a class="link" href="karma_confix_generator.html#spirit_repository.karma_components.directives.karma_confix_generator.description">Description</a>
         </h6>
 <p>
@@ -92,20 +93,20 @@
           tag using a simple: <code class="computeroutput"><span class="identifier">ol</span><span class="special">[</span><span class="string">"Some text"</span><span class="special">]</span></code> (which results in <code class="computeroutput"><span class="special"><</span><span class="identifier">ol</span><span class="special">></span><span class="identifier">Some</span> <span class="identifier">text</span><span class="special"></</span><span class="identifier">ol</span><span class="special">></span></code>).
         </p>
 <a name="spirit_repository.karma_components.directives.karma_confix_generator.header"></a><h6>
-<a name="id2707830"></a>
+<a name="id3156719"></a>
           <a class="link" href="karma_confix_generator.html#spirit_repository.karma_components.directives.karma_confix_generator.header">Header</a>
         </h6>
 <pre class="programlisting"><span class="comment">// forwards to <boost/spirit/repository/home/karma/directive/confix.hpp>
 </span><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">spirit</span><span class="special">/</span><span class="identifier">repository</span><span class="special">/</span><span class="identifier">include</span><span class="special">/</span><span class="identifier">karma_confix</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
 </pre>
 <a name="spirit_repository.karma_components.directives.karma_confix_generator.synopsis"></a><h6>
-<a name="id2707933"></a>
+<a name="id3156822"></a>
           <a class="link" href="karma_confix_generator.html#spirit_repository.karma_components.directives.karma_confix_generator.synopsis">Synopsis</a>
         </h6>
 <pre class="programlisting"><span class="identifier">confix</span><span class="special">(</span><span class="identifier">prefix</span><span class="special">,</span> <span class="identifier">suffix</span><span class="special">)[</span><span class="identifier">subject</span><span class="special">]</span>
 </pre>
 <a name="spirit_repository.karma_components.directives.karma_confix_generator.parameters"></a><h6>
-<a name="id2707998"></a>
+<a name="id3156889"></a>
           <a class="link" href="karma_confix_generator.html#spirit_repository.karma_components.directives.karma_confix_generator.parameters">Parameters</a>
         </h6>
 <div class="informaltable"><table class="table">
@@ -174,7 +175,7 @@
           All three parameters can be arbitrary complex generators themselves.
         </p>
 <a name="spirit_repository.karma_components.directives.karma_confix_generator.attribute"></a><h6>
-<a name="id2708199"></a>
+<a name="id3157088"></a>
           <a class="link" href="karma_confix_generator.html#spirit_repository.karma_components.directives.karma_confix_generator.attribute">Attribute</a>
         </h6>
 <p>
@@ -201,7 +202,7 @@
           </p></td></tr>
 </table></div>
 <a name="spirit_repository.karma_components.directives.karma_confix_generator.example"></a><h6>
-<a name="id2708439"></a>
+<a name="id3157327"></a>
           <a class="link" href="karma_confix_generator.html#spirit_repository.karma_components.directives.karma_confix_generator.example">Example</a>
         </h6>
 <p>
@@ -210,7 +211,7 @@
           styles and a function prototype (for the full example code see here: confix.cpp)
         </p>
 <a name="spirit_repository.karma_components.directives.karma_confix_generator.prerequisites"></a><h6>
-<a name="id2708487"></a>
+<a name="id3157375"></a>
           <a class="link" href="karma_confix_generator.html#spirit_repository.karma_components.directives.karma_confix_generator.prerequisites">Prerequisites</a>
         </h6>
 <p>
@@ -248,7 +249,7 @@
 <p>
         </p>
 <a name="spirit_repository.karma_components.directives.karma_confix_generator.generating_different_comment_styles"></a><h6>
-<a name="id2708799"></a>
+<a name="id3157687"></a>
           <a class="link" href="karma_confix_generator.html#spirit_repository.karma_components.directives.karma_confix_generator.generating_different_comment_styles">Generating
           Different Comment Styles</a>
         </h6>
@@ -300,7 +301,7 @@
           */</span> </code>.
         </p>
 <a name="spirit_repository.karma_components.directives.karma_confix_generator.generating_a_function_prototype"></a><h6>
-<a name="id2709182"></a>
+<a name="id3158070"></a>
           <a class="link" href="karma_confix_generator.html#spirit_repository.karma_components.directives.karma_confix_generator.generating_a_function_prototype">Generating
           a Function Prototype</a>
         </h6>
@@ -345,7 +346,7 @@
 </tr></table>
 <hr>
 <div class="spirit-nav">
-<a accesskey="p" href="../directives.html"><img src="../../../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../directives.html"><img src="../../../../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../../../../../../doc/html/images/home.png" alt="Home"></a>
+<a accesskey="p" href="../directives.html"><img src="../../../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../directives.html"><img src="../../../../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="../nonterminal.html"><img src="../../../../../../../../doc/html/images/next.png" alt="Next"></a>
 </div>
 </body>
 </html>
Added: trunk/libs/spirit/repository/doc/html/spirit_repository/karma_components/nonterminal.html
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/repository/doc/html/spirit_repository/karma_components/nonterminal.html	2009-08-14 12:39:56 EDT (Fri, 14 Aug 2009)
@@ -0,0 +1,47 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>Karma Generator Non-terminals</title>
+<link rel="stylesheet" href="../../../../../../../doc/html/boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.75.0">
+<link rel="home" href="../../index.html" title="Spirit Repository 0.1">
+<link rel="up" href="../karma_components.html" title="Karma Components">
+<link rel="prev" href="directives/karma_confix_generator.html" title="Karma Confix Generator">
+<link rel="next" href="nonterminal/subrule.html" title="Karma subrules">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><tr>
+<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
+<td align="center">Home</td>
+<td align="center">Libraries</td>
+<td align="center">People</td>
+<td align="center">FAQ</td>
+<td align="center">More</td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="directives/karma_confix_generator.html"><img src="../../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../karma_components.html"><img src="../../../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="nonterminal/subrule.html"><img src="../../../../../../../doc/html/images/next.png" alt="Next"></a>
+</div>
+<div class="section" title="Karma Generator Non-terminals">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="spirit_repository.karma_components.nonterminal"></a><a class="link" href="nonterminal.html" title="Karma Generator Non-terminals"> Karma
+      Generator Non-terminals</a>
+</h3></div></div></div>
+<div class="toc"><dl><dt><span class="section"><a href="nonterminal/subrule.html">
+        Karma subrules</a></span></dt></dl></div>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><div class="copyright-footer">Copyright © 2001-2009 Joel
+      de Guzman, Hartmut Kaiser<p>
+        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)
+      </p>
+</div></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="directives/karma_confix_generator.html"><img src="../../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../karma_components.html"><img src="../../../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="nonterminal/subrule.html"><img src="../../../../../../../doc/html/images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>
Added: trunk/libs/spirit/repository/doc/html/spirit_repository/karma_components/nonterminal/subrule.html
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/repository/doc/html/spirit_repository/karma_components/nonterminal/subrule.html	2009-08-14 12:39:56 EDT (Fri, 14 Aug 2009)
@@ -0,0 +1,512 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>Karma subrules</title>
+<link rel="stylesheet" href="../../../../../../../../doc/html/boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.75.0">
+<link rel="home" href="../../../index.html" title="Spirit Repository 0.1">
+<link rel="up" href="../nonterminal.html" title="Karma Generator Non-terminals">
+<link rel="prev" href="../nonterminal.html" title="Karma Generator Non-terminals">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><tr>
+<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../../boost.png"></td>
+<td align="center">Home</td>
+<td align="center">Libraries</td>
+<td align="center">People</td>
+<td align="center">FAQ</td>
+<td align="center">More</td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="../nonterminal.html"><img src="../../../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../nonterminal.html"><img src="../../../../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../../../../../../doc/html/images/home.png" alt="Home"></a>
+</div>
+<div class="section" title="Karma subrules">
+<div class="titlepage"><div><div><h4 class="title">
+<a name="spirit_repository.karma_components.nonterminal.subrule"></a><a class="link" href="subrule.html" title="Karma subrules">
+        Karma subrules</a>
+</h4></div></div></div>
+<a name="spirit_repository.karma_components.nonterminal.subrule.description"></a><h6>
+<a name="id3158498"></a>
+          <a class="link" href="subrule.html#spirit_repository.karma_components.nonterminal.subrule.description">Description</a>
+        </h6>
+<p>
+          The <span class="emphasis"><em>Spirit.Karma</em></span> <code class="computeroutput"><span class="identifier">subrule</span></code>
+          is a component allowing to create a named generator, and to refer to it
+          by name -- much like rules and grammars. It is in fact a fully static version
+          of the rule.
+        </p>
+<p>
+          The strength of subrules is performance. Replacing some rules with subrules
+          can make a generator slightly faster (see <a class="link" href="subrule.html#spirit_repository.karma_components.nonterminal.subrule.performance">Performance</a>
+          below for measurements). The reason is that subrules allow aggressive inlining
+          by the C++ compiler, whereas the implementation of rules is based on a
+          virtual function call which, depending on the compiler, can have some run-time
+          overhead and stop inlining.
+        </p>
+<p>
+          The weaknesses of subrules are:
+        </p>
+<div class="itemizedlist"><ul class="itemizedlist" type="disc">
+<li class="listitem">
+            subrules can only be defined and used within the same generator expression.
+            A subrule cannot be defined at one location, and then used in another
+            location.
+          </li>
+<li class="listitem">
+            subrules put a massive strain on the C++ compiler. They increase compile
+            times and memory usage during compilation, and also increase the risk
+            of hitting compiler limits and/or bugs.
+          </li>
+</ul></div>
+<p>
+          </p>
+<p>
+            
+</p>
+<pre class="programlisting"><span class="identifier">entry</span> <span class="special">%=</span> <span class="special">(</span>
+    <span class="identifier">ast_node</span> <span class="special">%=</span> <span class="identifier">int_</span> <span class="special">|</span> <span class="identifier">binary_node</span> <span class="special">|</span> <span class="identifier">unary_node</span>
+
+  <span class="special">,</span> <span class="identifier">binary_node</span> <span class="special">%=</span> <span class="char">'('</span> <span class="special"><<</span> <span class="identifier">ast_node</span> <span class="special"><<</span> <span class="identifier">char_</span> <span class="special"><<</span> <span class="identifier">ast_node</span> <span class="special"><<</span> <span class="char">')'</span>
+
+  <span class="special">,</span> <span class="identifier">unary_node</span> <span class="special">%=</span> <span class="char">'('</span> <span class="special"><<</span> <span class="identifier">char_</span> <span class="special"><<</span> <span class="identifier">ast_node</span> <span class="special"><<</span> <span class="char">')'</span>
+<span class="special">);</span>
+</pre>
+<p>
+          </p>
+<p>
+        </p>
+<p>
+          The example above can be found here: ../../example/karma/mini_xml_karma_sr.cpp
+        </p>
+<p>
+          As shown in this code snippet (an extract from the mini_xml_karma_sr example),
+          subrules can be freely mixed with rules and grammars. Here, a group of
+          3 subrules (<code class="computeroutput"><span class="identifier">ast_node</span></code>,
+          <code class="computeroutput"><span class="identifier">binary_node</span></code>, <code class="computeroutput"><span class="identifier">unary_node</span></code>) is assigned to a rule (named
+          <code class="computeroutput"><span class="identifier">entry</span></code>). This means that
+          parts of a generator can use subrules (typically the innermost, most performance-critical
+          parts), whereas the rest can use rules and grammars.
+        </p>
+<a name="spirit_repository.karma_components.nonterminal.subrule.header"></a><h6>
+<a name="id3158846"></a>
+          <a class="link" href="subrule.html#spirit_repository.karma_components.nonterminal.subrule.header">Header</a>
+        </h6>
+<pre class="programlisting"><span class="comment">// forwards to <boost/spirit/repository/home/karma/nonterminal/subrule.hpp>
+</span><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">spirit</span><span class="special">/</span><span class="identifier">repository</span><span class="special">/</span><span class="identifier">include</span><span class="special">/</span><span class="identifier">karma_subrule</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
+</pre>
+<a name="spirit_repository.karma_components.nonterminal.subrule.synopsis__declaration_"></a><h6>
+<a name="id3158948"></a>
+          <a class="link" href="subrule.html#spirit_repository.karma_components.nonterminal.subrule.synopsis__declaration_">Synopsis
+          (declaration)</a>
+        </h6>
+<pre class="programlisting"><span class="identifier">subrule</span><span class="special"><</span><span class="identifier">ID</span><span class="special">,</span> <span class="identifier">A1</span><span class="special">,</span> <span class="identifier">A2</span><span class="special">,</span> <span class="identifier">A3</span><span class="special">></span> <span class="identifier">sr</span><span class="special">(</span><span class="identifier">name</span><span class="special">);</span>
+</pre>
+<a name="spirit_repository.karma_components.nonterminal.subrule.parameters__declaration_"></a><h6>
+<a name="id3159046"></a>
+          <a class="link" href="subrule.html#spirit_repository.karma_components.nonterminal.subrule.parameters__declaration_">Parameters
+          (declaration)</a>
+        </h6>
+<div class="informaltable"><table class="table">
+<colgroup>
+<col>
+<col>
+</colgroup>
+<thead><tr>
+<th>
+                <p>
+                  Parameter
+                </p>
+                </th>
+<th>
+                <p>
+                  Description
+                </p>
+                </th>
+</tr></thead>
+<tbody>
+<tr>
+<td>
+                <p>
+                  <code class="computeroutput"><span class="identifier">ID</span></code>
+                </p>
+                </td>
+<td>
+                <p>
+                  Required numeric argument. Gives the subrule a unique 'identification
+                  tag'.
+                </p>
+                </td>
+</tr>
+<tr>
+<td>
+                <p>
+                  <code class="computeroutput"><span class="identifier">A1</span></code>, <code class="computeroutput"><span class="identifier">A2</span></code>, <code class="computeroutput"><span class="identifier">A3</span></code>
+                </p>
+                </td>
+<td>
+                <p>
+                  Optional types, can be specified in any order. Can be one of 1.
+                  signature, 2. locals, 3. delimiter (see rules reference for more
+                  information on those parameters).
+                </p>
+                </td>
+</tr>
+<tr>
+<td>
+                <p>
+                  <code class="computeroutput"><span class="identifier">name</span></code>
+                </p>
+                </td>
+<td>
+                <p>
+                  Optional string. Gives the subrule a name, useful for debugging
+                  and error handling.
+                </p>
+                </td>
+</tr>
+</tbody>
+</table></div>
+<a name="spirit_repository.karma_components.nonterminal.subrule.synopsis__usage_"></a><h6>
+<a name="id3159208"></a>
+          <a class="link" href="subrule.html#spirit_repository.karma_components.nonterminal.subrule.synopsis__usage_">Synopsis
+          (usage)</a>
+        </h6>
+<p>
+          Subrules are defined and used within groups, typically (and by convention)
+          enclosed inside parentheses.
+        </p>
+<pre class="programlisting"><span class="comment">// Group containing N subrules
+</span><span class="special">(</span>
+    <span class="identifier">sr1</span> <span class="special">=</span> <span class="identifier">expr1</span>
+  <span class="special">,</span> <span class="identifier">sr2</span> <span class="special">=</span> <span class="identifier">expr2</span>
+  <span class="special">,</span> <span class="special">...</span> <span class="comment">// Any number of subrules
+</span><span class="special">}</span>
+</pre>
+<p>
+          The IDs of all subrules defined within the same group must be different.
+          It is an error to define several subrules with the same ID (or to define
+          the same subrule multiple times) in the same group.
+        </p>
+<pre class="programlisting"><span class="comment">// Auto-subrules and inherited attributes
+</span><span class="special">(</span>
+    <span class="identifier">srA</span> <span class="special">%=</span> <span class="identifier">exprA</span> <span class="special"><<</span> <span class="identifier">srB</span> <span class="special"><<</span> <span class="identifier">srC</span><span class="special">(</span><span class="identifier">c1</span><span class="special">,</span> <span class="identifier">c2</span><span class="special">,</span> <span class="special">...)</span> <span class="comment">// Arguments to subrule srC
+</span>  <span class="special">,</span> <span class="identifier">srB</span> <span class="special">%=</span> <span class="identifier">exprB</span>
+  <span class="special">,</span> <span class="identifier">srC</span>  <span class="special">=</span> <span class="identifier">exprC</span>
+  <span class="special">,</span> <span class="special">...</span>
+<span class="special">)(</span><span class="identifier">a1</span><span class="special">,</span> <span class="identifier">a2</span><span class="special">,</span> <span class="special">...)</span>         <span class="comment">// Arguments to group, i.e. to start subrule srA
+</span></pre>
+<a name="spirit_repository.karma_components.nonterminal.subrule.parameters__usage_"></a><h6>
+<a name="id3159501"></a>
+          <a class="link" href="subrule.html#spirit_repository.karma_components.nonterminal.subrule.parameters__usage_">Parameters
+          (usage)</a>
+        </h6>
+<div class="informaltable"><table class="table">
+<colgroup>
+<col>
+<col>
+</colgroup>
+<thead><tr>
+<th>
+                <p>
+                  Parameter
+                </p>
+                </th>
+<th>
+                <p>
+                  Description
+                </p>
+                </th>
+</tr></thead>
+<tbody>
+<tr>
+<td>
+                <p>
+                  <code class="computeroutput"><span class="identifier">sr1</span></code>, <code class="computeroutput"><span class="identifier">sr2</span></code>
+                </p>
+                </td>
+<td>
+                <p>
+                  Subrules with different IDs.
+                </p>
+                </td>
+</tr>
+<tr>
+<td>
+                <p>
+                  <code class="computeroutput"><span class="identifier">expr1</span></code>, <code class="computeroutput"><span class="identifier">expr2</span></code>
+                </p>
+                </td>
+<td>
+                <p>
+                  Generator expressions. Can include <code class="computeroutput"><span class="identifier">sr1</span></code>
+                  and <code class="computeroutput"><span class="identifier">sr2</span></code>, as well
+                  as any other valid generator expressions.
+                </p>
+                </td>
+</tr>
+<tr>
+<td>
+                <p>
+                  <code class="computeroutput"><span class="identifier">srA</span></code>
+                </p>
+                </td>
+<td>
+                <p>
+                  Subrule with a synthesized attribute and inherited attributes.
+                </p>
+                </td>
+</tr>
+<tr>
+<td>
+                <p>
+                  <code class="computeroutput"><span class="identifier">srB</span></code>
+                </p>
+                </td>
+<td>
+                <p>
+                  Subrule with a synthesized attribute.
+                </p>
+                </td>
+</tr>
+<tr>
+<td>
+                <p>
+                  <code class="computeroutput"><span class="identifier">srC</span></code>
+                </p>
+                </td>
+<td>
+                <p>
+                  Subrule with inherited attributes.
+                </p>
+                </td>
+</tr>
+<tr>
+<td>
+                <p>
+                  <code class="computeroutput"><span class="identifier">exprA</span></code>, <code class="computeroutput"><span class="identifier">exprB</span></code>, <code class="computeroutput"><span class="identifier">exprC</span></code>
+                </p>
+                </td>
+<td>
+                <p>
+                  Generator expressions.
+                </p>
+                </td>
+</tr>
+<tr>
+<td>
+                <p>
+                  <code class="computeroutput"><span class="identifier">a1</span></code>, <code class="computeroutput"><span class="identifier">a2</span></code>
+                </p>
+                </td>
+<td>
+                <p>
+                  Arguments passed to the subrule group. They are passed as inherited
+                  attributes to the group's start subrule, <code class="computeroutput"><span class="identifier">srA</span></code>.
+                </p>
+                </td>
+</tr>
+<tr>
+<td>
+                <p>
+                  <code class="computeroutput"><span class="identifier">c1</span></code>, <code class="computeroutput"><span class="identifier">c2</span></code>
+                </p>
+                </td>
+<td>
+                <p>
+                  Arguments passed as inherited attributes to subrule <code class="computeroutput"><span class="identifier">srC</span></code>.
+                </p>
+                </td>
+</tr>
+</tbody>
+</table></div>
+<a name="spirit_repository.karma_components.nonterminal.subrule.groups"></a><h6>
+<a name="id3159879"></a>
+          <a class="link" href="subrule.html#spirit_repository.karma_components.nonterminal.subrule.groups">Groups</a>
+        </h6>
+<p>
+          A subrule group (a set of subrule definitions) is a generator, which can
+          be used anywhere in a generator expression (in assignments to rules, as
+          well as directly in arguments to functions such as <code class="computeroutput"><span class="identifier">generate</span></code>).
+          In a group, generation proceeds from the start subrule, which is the first
+          (topmost) subrule defined in that group. In the two groups in the synopsis
+          above, <code class="computeroutput"><span class="identifier">sr1</span></code> and <code class="computeroutput"><span class="identifier">srA</span></code> are the start subrules respectively
+          -- for example when the first subrule group is called forth, the <code class="computeroutput"><span class="identifier">sr1</span></code> subrule is called.
+        </p>
+<p>
+          A subrule can only be used in a group which defines it. Groups can be viewed
+          as scopes: a definition of a subrule is limited to its enclosing group.
+        </p>
+<pre class="programlisting"><span class="identifier">rule</span><span class="special"><</span><span class="identifier">outiter_type</span><span class="special">></span> <span class="identifier">r1</span><span class="special">,</span> <span class="identifier">r2</span><span class="special">,</span> <span class="identifier">r3</span><span class="special">;</span>
+<span class="identifier">subrule</span><span class="special"><</span><span class="number">1</span><span class="special">></span> <span class="identifier">sr1</span><span class="special">;</span>
+<span class="identifier">subrule</span><span class="special"><</span><span class="number">2</span><span class="special">></span> <span class="identifier">sr2</span><span class="special">;</span>
+
+<span class="identifier">r1</span> <span class="special">=</span>
+        <span class="special">(</span> <span class="identifier">sr1</span> <span class="special">=</span> <span class="char">'a'</span> <span class="special"><<</span> <span class="identifier">space</span> <span class="special">)</span>      <span class="comment">// First group in r1.
+</span>    <span class="special"><<</span>  <span class="special">(</span> <span class="identifier">sr2</span> <span class="special">=</span> <span class="special">+</span><span class="identifier">sr1</span> <span class="special">)</span>              <span class="comment">// Second group in r1.
+</span>    <span class="comment">//           ^^^
+</span>    <span class="comment">// DOES NOT COMPILE: sr1 is not defined in this
+</span>    <span class="comment">// second group, it cannot be used here (its
+</span>    <span class="comment">// previous definition is out of scope).
+</span><span class="special">;</span>
+
+<span class="identifier">r2</span> <span class="special">=</span>
+        <span class="special">(</span> <span class="identifier">sr1</span> <span class="special">=</span> <span class="char">'a'</span> <span class="special"><<</span> <span class="identifier">space</span> <span class="special">)</span>      <span class="comment">// Only group in r2.
+</span>    <span class="special"><<</span>  <span class="identifier">sr1</span>
+    <span class="comment">//  ^^^
+</span>    <span class="comment">// DOES NOT COMPILE: not in a subrule group,
+</span>    <span class="comment">// sr1 cannot be used here (here too, its
+</span>    <span class="comment">// previous definition is out of scope).
+</span><span class="special">;</span>
+
+<span class="identifier">r3</span> <span class="special">=</span>
+        <span class="special">(</span> <span class="identifier">sr1</span> <span class="special">=</span> <span class="identifier">space</span> <span class="special"><<</span> <span class="char">'x'</span> <span class="special">)</span>      <span class="comment">// Another group. The same subrule `sr1`
+</span>                                    <span class="comment">// can have another, independent
+</span>                                    <span class="comment">// definition in this group.
+</span><span class="special">;</span>
+</pre>
+<a name="spirit_repository.karma_components.nonterminal.subrule.attributes"></a><h6>
+<a name="id3160373"></a>
+          <a class="link" href="subrule.html#spirit_repository.karma_components.nonterminal.subrule.attributes">Attributes</a>
+        </h6>
+<p>
+          A subrule has the same behavior as a rule with respect to attributes. In
+          particular:
+        </p>
+<div class="itemizedlist"><ul class="itemizedlist" type="disc">
+<li class="listitem">
+            the type of its synthesized attribute is the one specified in the subrule's
+            signature, if any. Otherwise it is <code class="computeroutput"><span class="identifier">unused_type</span></code>.
+          </li>
+<li class="listitem">
+            the types of its inherited attributes are the ones specified in the subrule's
+            signature, if any. Otherwise the subrule has no inherited attributes.
+          </li>
+<li class="listitem">
+            an auto-subrule can be defined by assigning it with the <code class="computeroutput"><span class="special">%=</span></code> syntax. In this case, the subrule's
+            synthesized attribute is automatically propagated to the RHS generator's
+            attribute.
+          </li>
+<li class="listitem">
+            the Phoenix placeholders <code class="computeroutput"><span class="identifier">_val</span></code>,
+            <code class="computeroutput"><span class="identifier">_r1</span></code>, <code class="computeroutput"><span class="identifier">_r2</span></code>,
+            ... are available to refer to the subrule's synthesized and inherited
+            attributes, if present.
+          </li>
+</ul></div>
+<a name="spirit_repository.karma_components.nonterminal.subrule.locals"></a><h6>
+<a name="id3160483"></a>
+          <a class="link" href="subrule.html#spirit_repository.karma_components.nonterminal.subrule.locals">Locals</a>
+        </h6>
+<p>
+          A subrule has the same behavior as a rule with respect to locals. In particular,
+          the Phoenix placeholders <code class="computeroutput"><span class="identifier">_a</span></code>,
+          <code class="computeroutput"><span class="identifier">_b</span></code>, ... are available to
+          refer to the subrule's locals, if present.
+        </p>
+<a name="spirit_repository.karma_components.nonterminal.subrule.example"></a><h6>
+<a name="id3160533"></a>
+          <a class="link" href="subrule.html#spirit_repository.karma_components.nonterminal.subrule.example">Example</a>
+        </h6>
+<p>
+          Some includes:
+        </p>
+<p>
+          </p>
+<p>
+            
+</p>
+<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">spirit</span><span class="special">/</span><span class="identifier">include</span><span class="special">/</span><span class="identifier">karma</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
+<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">spirit</span><span class="special">/</span><span class="identifier">repository</span><span class="special">/</span><span class="identifier">include</span><span class="special">/</span><span class="identifier">karma_subrule</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
+<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">spirit</span><span class="special">/</span><span class="identifier">include</span><span class="special">/</span><span class="identifier">phoenix_core</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
+<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">spirit</span><span class="special">/</span><span class="identifier">include</span><span class="special">/</span><span class="identifier">phoenix_operator</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
+<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">spirit</span><span class="special">/</span><span class="identifier">include</span><span class="special">/</span><span class="identifier">phoenix_fusion</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
+</pre>
+<p>
+          </p>
+<p>
+        </p>
+<p>
+          Some using declarations:
+        </p>
+<p>
+          </p>
+<p>
+            
+</p>
+<pre class="programlisting"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">spirit</span><span class="special">;</span>
+<span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">spirit</span><span class="special">::</span><span class="identifier">ascii</span><span class="special">;</span>
+<span class="keyword">namespace</span> <span class="identifier">repo</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">spirit</span><span class="special">::</span><span class="identifier">repository</span><span class="special">;</span>
+</pre>
+<p>
+          </p>
+<p>
+        </p>
+<p>
+          A grammar containing only one rule, defined with a group of 2 subrules:
+        </p>
+<p>
+          </p>
+<p>
+            
+</p>
+<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">OutputIterator</span><span class="special">></span>
+<span class="keyword">struct</span> <span class="identifier">mini_xml_generator</span>
+  <span class="special">:</span> <span class="identifier">karma</span><span class="special">::</span><span class="identifier">grammar</span><span class="special"><</span><span class="identifier">OutputIterator</span><span class="special">,</span> <span class="identifier">mini_xml</span><span class="special">()></span>
+<span class="special">{</span>
+    <span class="identifier">mini_xml_generator</span><span class="special">()</span> <span class="special">:</span> <span class="identifier">mini_xml_generator</span><span class="special">::</span><span class="identifier">base_type</span><span class="special">(</span><span class="identifier">entry</span><span class="special">)</span>
+    <span class="special">{</span>
+        <span class="comment">//[mini_xml_karma_sr_def
+</span>        <span class="identifier">entry</span> <span class="special">%=</span> <span class="special">(</span>
+            <span class="identifier">xml</span> <span class="special">=</span> 
+                    <span class="char">'<'</span>  <span class="special"><<</span> <span class="identifier">string</span><span class="special">[</span><span class="identifier">_1</span> <span class="special">=</span> <span class="identifier">at_c</span><span class="special"><</span><span class="number">0</span><span class="special">>(</span><span class="identifier">_val</span><span class="special">)]</span> <span class="special"><<</span> <span class="char">'>'</span>
+                <span class="special"><<</span>         <span class="special">(*</span><span class="identifier">node</span><span class="special">)[</span><span class="identifier">_1</span> <span class="special">=</span> <span class="identifier">at_c</span><span class="special"><</span><span class="number">1</span><span class="special">>(</span><span class="identifier">_val</span><span class="special">)]</span>
+                <span class="special"><<</span>  <span class="string">"</"</span> <span class="special"><<</span> <span class="identifier">string</span><span class="special">[</span><span class="identifier">_1</span> <span class="special">=</span> <span class="identifier">at_c</span><span class="special"><</span><span class="number">0</span><span class="special">>(</span><span class="identifier">_val</span><span class="special">)]</span> <span class="special"><<</span> <span class="char">'>'</span>
+
+          <span class="special">,</span> <span class="identifier">node</span> <span class="special">%=</span> <span class="identifier">string</span> <span class="special">|</span> <span class="identifier">xml</span>
+        <span class="special">);</span>
+        </pre>
+<p>
+          </p>
+<p>
+        </p>
+<p>
+          The definitions of the <code class="computeroutput"><span class="identifier">mini_xml</span></code>
+          and <code class="computeroutput"><span class="identifier">mini_xml_node</span></code> data
+          structures are not shown here. The full example above can be found here:
+          ../../example/karma/mini_xml_karma_sr.cpp
+        </p>
+<a name="spirit_repository.karma_components.nonterminal.subrule.performance"></a><h6>
+<a name="id3161466"></a>
+          <a class="link" href="subrule.html#spirit_repository.karma_components.nonterminal.subrule.performance">Performance</a>
+        </h6>
+<p>
+          For comparison of run-time and compile-time performance when using subrules,
+          please see the <a class="link" href="../../qi_components/nonterminal/subrule.html#spirit_repository.qi_components.nonterminal.subrule.performance">Performance</a>
+          section of <span class="emphasis"><em>Spirit.Qi</em></span> subrules (the implementation
+          of <span class="emphasis"><em>Spirit.Karma</em></span> and <span class="emphasis"><em>Spirit.Qi</em></span>
+          subrules is very similar, so performance is very similar too).
+        </p>
+<a name="spirit_repository.karma_components.nonterminal.subrule.notes"></a><h6>
+<a name="id3161515"></a>
+          <a class="link" href="subrule.html#spirit_repository.karma_components.nonterminal.subrule.notes">Notes</a>
+        </h6>
+<p>
+          FIXME add compiler-specific bit (MSVC pragmas, g++ option)
+        </p>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><div class="copyright-footer">Copyright © 2001-2009 Joel
+      de Guzman, Hartmut Kaiser<p>
+        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)
+      </p>
+</div></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="../nonterminal.html"><img src="../../../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../nonterminal.html"><img src="../../../../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../../../../../../doc/html/images/home.png" alt="Home"></a>
+</div>
+</body>
+</html>
Modified: trunk/libs/spirit/repository/doc/html/spirit_repository/preface.html
==============================================================================
--- trunk/libs/spirit/repository/doc/html/spirit_repository/preface.html	(original)
+++ trunk/libs/spirit/repository/doc/html/spirit_repository/preface.html	2009-08-14 12:39:56 EDT (Fri, 14 Aug 2009)
@@ -27,7 +27,7 @@
 <a name="spirit_repository.preface"></a><a class="link" href="preface.html" title="Preface">Preface</a>
 </h2></div></div></div>
 <a name="spirit_repository.preface.the_spirit_repository"></a><h4>
-<a name="id2646862"></a>
+<a name="id3095715"></a>
       <a class="link" href="preface.html#spirit_repository.preface.the_spirit_repository">The Spirit
       Repository</a>
     </h4>
@@ -77,7 +77,7 @@
       core library.
     </p>
 <a name="spirit_repository.preface.how_to_use_this_manual"></a><h4>
-<a name="id2649344"></a>
+<a name="id3098197"></a>
       <a class="link" href="preface.html#spirit_repository.preface.how_to_use_this_manual">How to use
       this manual</a>
     </h4>
@@ -86,7 +86,7 @@
       icons precede some text to indicate:
     </p>
 <div class="table">
-<a name="id2649364"></a><p class="title"><b>Table 1. Icons</b></p>
+<a name="id3098217"></a><p class="title"><b>Table 1. Icons</b></p>
 <div class="table-contents"><table class="table" summary="Icons">
 <colgroup>
 <col>
@@ -207,7 +207,7 @@
       Tools</a>.
     </p>
 <a name="spirit_repository.preface.support"></a><h4>
-<a name="id2645098"></a>
+<a name="id3093952"></a>
       <a class="link" href="preface.html#spirit_repository.preface.support">Support</a>
     </h4>
 <p>
Modified: trunk/libs/spirit/repository/doc/html/spirit_repository/qi_components/directives/confix.html
==============================================================================
--- trunk/libs/spirit/repository/doc/html/spirit_repository/qi_components/directives/confix.html	(original)
+++ trunk/libs/spirit/repository/doc/html/spirit_repository/qi_components/directives/confix.html	2009-08-14 12:39:56 EDT (Fri, 14 Aug 2009)
@@ -28,7 +28,7 @@
         Qi Confix Parser Directive</a>
 </h4></div></div></div>
 <a name="spirit_repository.qi_components.directives.confix.description"></a><h6>
-<a name="id2695643"></a>
+<a name="id3144497"></a>
           <a class="link" href="confix.html#spirit_repository.qi_components.directives.confix.description">Description</a>
         </h6>
 <p>
@@ -95,20 +95,20 @@
           </p></td></tr>
 </table></div>
 <a name="spirit_repository.qi_components.directives.confix.header"></a><h6>
-<a name="id2696600"></a>
+<a name="id3145454"></a>
           <a class="link" href="confix.html#spirit_repository.qi_components.directives.confix.header">Header</a>
         </h6>
 <pre class="programlisting"><span class="comment">// forwards to <boost/spirit/repository/home/qi/directive/confix.hpp>
 </span><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">spirit</span><span class="special">/</span><span class="identifier">repository</span><span class="special">/</span><span class="identifier">include</span><span class="special">/</span><span class="identifier">qi_confix</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
 </pre>
 <a name="spirit_repository.qi_components.directives.confix.synopsis"></a><h6>
-<a name="id2696701"></a>
+<a name="id3145554"></a>
           <a class="link" href="confix.html#spirit_repository.qi_components.directives.confix.synopsis">Synopsis</a>
         </h6>
 <pre class="programlisting"><span class="identifier">confix</span><span class="special">(</span><span class="identifier">prefix</span><span class="special">,</span> <span class="identifier">suffix</span><span class="special">)[</span><span class="identifier">subject</span><span class="special">]</span>
 </pre>
 <a name="spirit_repository.qi_components.directives.confix.parameters"></a><h6>
-<a name="id2696768"></a>
+<a name="id3145622"></a>
           <a class="link" href="confix.html#spirit_repository.qi_components.directives.confix.parameters">Parameters</a>
         </h6>
 <div class="informaltable"><table class="table">
@@ -172,7 +172,7 @@
           All three parameters can be arbitrarily complex parsers themselves.
         </p>
 <a name="spirit_repository.qi_components.directives.confix.attribute"></a><h6>
-<a name="id2696931"></a>
+<a name="id3145785"></a>
           <a class="link" href="confix.html#spirit_repository.qi_components.directives.confix.attribute">Attribute</a>
         </h6>
 <p>
@@ -198,7 +198,7 @@
           </p></td></tr>
 </table></div>
 <a name="spirit_repository.qi_components.directives.confix.example"></a><h6>
-<a name="id2697244"></a>
+<a name="id3146097"></a>
           <a class="link" href="confix.html#spirit_repository.qi_components.directives.confix.example">Example</a>
         </h6>
 <p>
@@ -208,7 +208,7 @@
           see confix.cpp)
         </p>
 <a name="spirit_repository.qi_components.directives.confix.prerequisites"></a><h6>
-<a name="id2697291"></a>
+<a name="id3146144"></a>
           <a class="link" href="confix.html#spirit_repository.qi_components.directives.confix.prerequisites">Prerequisites</a>
         </h6>
 <p>
@@ -251,7 +251,7 @@
 <p>
         </p>
 <a name="spirit_repository.qi_components.directives.confix.parsing_different_comment_styles"></a><h6>
-<a name="id2697814"></a>
+<a name="id3146667"></a>
           <a class="link" href="confix.html#spirit_repository.qi_components.directives.confix.parsing_different_comment_styles">Parsing
           Different Comment Styles</a>
         </h6>
@@ -311,7 +311,7 @@
           This is a comment */</span> </code>".
         </p>
 <a name="spirit_repository.qi_components.directives.confix.parsing_tagged_data"></a><h6>
-<a name="id2698523"></a>
+<a name="id3147376"></a>
           <a class="link" href="confix.html#spirit_repository.qi_components.directives.confix.parsing_tagged_data">Parsing
           Tagged Data</a>
         </h6>
Modified: trunk/libs/spirit/repository/doc/html/spirit_repository/qi_components/directives/distinct.html
==============================================================================
--- trunk/libs/spirit/repository/doc/html/spirit_repository/qi_components/directives/distinct.html	(original)
+++ trunk/libs/spirit/repository/doc/html/spirit_repository/qi_components/directives/distinct.html	2009-08-14 12:39:56 EDT (Fri, 14 Aug 2009)
@@ -28,7 +28,7 @@
         Qi Distinct Parser Directive</a>
 </h4></div></div></div>
 <a name="spirit_repository.qi_components.directives.distinct.description"></a><h6>
-<a name="id2698962"></a>
+<a name="id3147815"></a>
           <a class="link" href="distinct.html#spirit_repository.qi_components.directives.distinct.description">Description</a>
         </h6>
 <p>
@@ -144,20 +144,20 @@
           above.
         </p>
 <a name="spirit_repository.qi_components.directives.distinct.header"></a><h6>
-<a name="id2700522"></a>
+<a name="id3149376"></a>
           <a class="link" href="distinct.html#spirit_repository.qi_components.directives.distinct.header">Header</a>
         </h6>
 <pre class="programlisting"><span class="comment">// forwards to <boost/spirit/repository/home/qi/directive/distinct.hpp>
 </span><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">spirit</span><span class="special">/</span><span class="identifier">repository</span><span class="special">/</span><span class="identifier">include</span><span class="special">/</span><span class="identifier">qi_distinct</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
 </pre>
 <a name="spirit_repository.qi_components.directives.distinct.synopsis"></a><h6>
-<a name="id2700625"></a>
+<a name="id3149478"></a>
           <a class="link" href="distinct.html#spirit_repository.qi_components.directives.distinct.synopsis">Synopsis</a>
         </h6>
 <pre class="programlisting"><span class="identifier">distinct</span><span class="special">(</span><span class="identifier">tail</span><span class="special">)[</span><span class="identifier">subject</span><span class="special">]</span>
 </pre>
 <a name="spirit_repository.qi_components.directives.distinct.parameters"></a><h6>
-<a name="id2700681"></a>
+<a name="id3149534"></a>
           <a class="link" href="distinct.html#spirit_repository.qi_components.directives.distinct.parameters">Parameters</a>
         </h6>
 <div class="informaltable"><table class="table">
@@ -210,7 +210,7 @@
           All two parameters can be arbitrary complex parsers themselves.
         </p>
 <a name="spirit_repository.qi_components.directives.distinct.attribute"></a><h6>
-<a name="id2700798"></a>
+<a name="id3149652"></a>
           <a class="link" href="distinct.html#spirit_repository.qi_components.directives.distinct.attribute">Attribute</a>
         </h6>
 <p>
@@ -224,7 +224,7 @@
 <pre class="programlisting"><span class="identifier">a</span><span class="special">:</span> <span class="identifier">A</span><span class="special">,</span> <span class="identifier">b</span><span class="special">:</span> <span class="identifier">B</span> <span class="special">--></span> <span class="identifier">distinct</span><span class="special">(</span><span class="identifier">b</span><span class="special">)[</span><span class="identifier">a</span><span class="special">]:</span> <span class="identifier">A</span>
 </pre>
 <a name="spirit_repository.qi_components.directives.distinct.example"></a><h6>
-<a name="id2700950"></a>
+<a name="id3149804"></a>
           <a class="link" href="distinct.html#spirit_repository.qi_components.directives.distinct.example">Example</a>
         </h6>
 <p>
@@ -232,7 +232,7 @@
           parser. distinct.cpp)
         </p>
 <a name="spirit_repository.qi_components.directives.distinct.prerequisites"></a><h6>
-<a name="id2700994"></a>
+<a name="id3149847"></a>
           <a class="link" href="distinct.html#spirit_repository.qi_components.directives.distinct.prerequisites">Prerequisites</a>
         </h6>
 <p>
@@ -269,7 +269,7 @@
 <p>
         </p>
 <a name="spirit_repository.qi_components.directives.distinct.using_the_distinct_directive_to_match_keywords"></a><h6>
-<a name="id2701302"></a>
+<a name="id3150156"></a>
           <a class="link" href="distinct.html#spirit_repository.qi_components.directives.distinct.using_the_distinct_directive_to_match_keywords">Using
           The Distinct Directive to Match keywords</a>
         </h6>
Modified: trunk/libs/spirit/repository/doc/html/spirit_repository/qi_components/nonterminal/subrule.html
==============================================================================
--- trunk/libs/spirit/repository/doc/html/spirit_repository/qi_components/nonterminal/subrule.html	(original)
+++ trunk/libs/spirit/repository/doc/html/spirit_repository/qi_components/nonterminal/subrule.html	2009-08-14 12:39:56 EDT (Fri, 14 Aug 2009)
@@ -28,7 +28,7 @@
         Qi subrules</a>
 </h4></div></div></div>
 <a name="spirit_repository.qi_components.nonterminal.subrule.description"></a><h6>
-<a name="id2702457"></a>
+<a name="id3151310"></a>
           <a class="link" href="subrule.html#spirit_repository.qi_components.nonterminal.subrule.description">Description</a>
         </h6>
 <p>
@@ -101,21 +101,21 @@
           most performance-critical parts), whereas the rest can use rules and grammars.
         </p>
 <a name="spirit_repository.qi_components.nonterminal.subrule.header"></a><h6>
-<a name="id2702944"></a>
+<a name="id3151798"></a>
           <a class="link" href="subrule.html#spirit_repository.qi_components.nonterminal.subrule.header">Header</a>
         </h6>
 <pre class="programlisting"><span class="comment">// forwards to <boost/spirit/repository/home/qi/nonterminal/subrule.hpp>
 </span><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">spirit</span><span class="special">/</span><span class="identifier">repository</span><span class="special">/</span><span class="identifier">include</span><span class="special">/</span><span class="identifier">qi_subrule</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
 </pre>
 <a name="spirit_repository.qi_components.nonterminal.subrule.synopsis__declaration_"></a><h6>
-<a name="id2703046"></a>
+<a name="id3151900"></a>
           <a class="link" href="subrule.html#spirit_repository.qi_components.nonterminal.subrule.synopsis__declaration_">Synopsis
           (declaration)</a>
         </h6>
 <pre class="programlisting"><span class="identifier">subrule</span><span class="special"><</span><span class="identifier">ID</span><span class="special">,</span> <span class="identifier">A1</span><span class="special">,</span> <span class="identifier">A2</span><span class="special">,</span> <span class="identifier">A3</span><span class="special">></span> <span class="identifier">sr</span><span class="special">(</span><span class="identifier">name</span><span class="special">);</span>
 </pre>
 <a name="spirit_repository.qi_components.nonterminal.subrule.parameters__declaration_"></a><h6>
-<a name="id2703144"></a>
+<a name="id3151998"></a>
           <a class="link" href="subrule.html#spirit_repository.qi_components.nonterminal.subrule.parameters__declaration_">Parameters
           (declaration)</a>
         </h6>
@@ -180,7 +180,7 @@
 </tbody>
 </table></div>
 <a name="spirit_repository.qi_components.nonterminal.subrule.synopsis__usage_"></a><h6>
-<a name="id2703307"></a>
+<a name="id3152160"></a>
           <a class="link" href="subrule.html#spirit_repository.qi_components.nonterminal.subrule.synopsis__usage_">Synopsis
           (usage)</a>
         </h6>
@@ -209,7 +209,7 @@
 <span class="special">)(</span><span class="identifier">a1</span><span class="special">,</span> <span class="identifier">a2</span><span class="special">,</span> <span class="special">...)</span>         <span class="comment">// Arguments to group, i.e. to start subrule srA
 </span></pre>
 <a name="spirit_repository.qi_components.nonterminal.subrule.parameters__usage_"></a><h6>
-<a name="id2703601"></a>
+<a name="id3152455"></a>
           <a class="link" href="subrule.html#spirit_repository.qi_components.nonterminal.subrule.parameters__usage_">Parameters
           (usage)</a>
         </h6>
@@ -333,7 +333,7 @@
 </tbody>
 </table></div>
 <a name="spirit_repository.qi_components.nonterminal.subrule.groups"></a><h6>
-<a name="id2703978"></a>
+<a name="id3152831"></a>
           <a class="link" href="subrule.html#spirit_repository.qi_components.nonterminal.subrule.groups">Groups</a>
         </h6>
 <p>
@@ -378,7 +378,7 @@
 </span><span class="special">;</span>
 </pre>
 <a name="spirit_repository.qi_components.nonterminal.subrule.attributes"></a><h6>
-<a name="id2704480"></a>
+<a name="id3153333"></a>
           <a class="link" href="subrule.html#spirit_repository.qi_components.nonterminal.subrule.attributes">Attributes</a>
         </h6>
 <p>
@@ -406,7 +406,7 @@
           </li>
 </ul></div>
 <a name="spirit_repository.qi_components.nonterminal.subrule.locals"></a><h6>
-<a name="id2704589"></a>
+<a name="id3153442"></a>
           <a class="link" href="subrule.html#spirit_repository.qi_components.nonterminal.subrule.locals">Locals</a>
         </h6>
 <p>
@@ -416,7 +416,7 @@
           refer to the subrule's locals, if present.
         </p>
 <a name="spirit_repository.qi_components.nonterminal.subrule.example"></a><h6>
-<a name="id2704639"></a>
+<a name="id3153493"></a>
           <a class="link" href="subrule.html#spirit_repository.qi_components.nonterminal.subrule.example">Example</a>
         </h6>
 <p>
@@ -516,7 +516,7 @@
           <a href="../../../../../example/qi/mini_xml2_sr.cpp" target="_top">../../example/qi/mini_xml2_sr.cpp</a>
         </p>
 <a name="spirit_repository.qi_components.nonterminal.subrule.performance"></a><h6>
-<a name="id2706281"></a>
+<a name="id3155135"></a>
           <a class="link" href="subrule.html#spirit_repository.qi_components.nonterminal.subrule.performance">Performance</a>
         </h6>
 <p>
@@ -524,7 +524,7 @@
           examples to subrules, with various compilers.
         </p>
 <div class="table">
-<a name="id2706301"></a><p class="title"><b>Table 2. Subrules performance</b></p>
+<a name="id3155155"></a><p class="title"><b>Table 2. Subrules performance</b></p>
 <div class="table-contents"><table class="table" summary="Subrules performance">
 <colgroup>
 <col>
@@ -704,6 +704,33 @@
               </td>
 <td>
               <p>
+                Visual C++ 2005 (VC8) SP1
+              </p>
+              </td>
+<td>
+              <p>
+                +1%
+              </p>
+              </td>
+<td>
+              <p>
+                +33%
+              </p>
+              </td>
+<td>
+              <p>
+                +27%
+              </p>
+              </td>
+</tr>
+<tr>
+<td>
+              <p>
+                mini_xml2_sr
+              </p>
+              </td>
+<td>
+              <p>
                 Visual C++ 2008 (VC9)
               </p>
               </td>
@@ -744,7 +771,7 @@
           </li>
 </ul></div>
 <a name="spirit_repository.qi_components.nonterminal.subrule.notes"></a><h6>
-<a name="id2706612"></a>
+<a name="id3155501"></a>
           <a class="link" href="subrule.html#spirit_repository.qi_components.nonterminal.subrule.notes">Notes</a>
         </h6>
 <p>
Modified: trunk/libs/spirit/repository/doc/html/spirit_repository/qi_components/primitive/flush_multi_pass.html
==============================================================================
--- trunk/libs/spirit/repository/doc/html/spirit_repository/qi_components/primitive/flush_multi_pass.html	(original)
+++ trunk/libs/spirit/repository/doc/html/spirit_repository/qi_components/primitive/flush_multi_pass.html	2009-08-14 12:39:56 EDT (Fri, 14 Aug 2009)
@@ -28,7 +28,7 @@
         Qi flush_multi_pass parser</a>
 </h4></div></div></div>
 <a name="spirit_repository.qi_components.primitive.flush_multi_pass.description"></a><h6>
-<a name="id2645212"></a>
+<a name="id3094066"></a>
           <a class="link" href="flush_multi_pass.html#spirit_repository.qi_components.primitive.flush_multi_pass.description">Description</a>
         </h6>
 <p>
@@ -53,20 +53,20 @@
           <code class="computeroutput"><span class="identifier">eps</span></code>).
         </p>
 <a name="spirit_repository.qi_components.primitive.flush_multi_pass.header"></a><h6>
-<a name="id2645382"></a>
+<a name="id3094236"></a>
           <a class="link" href="flush_multi_pass.html#spirit_repository.qi_components.primitive.flush_multi_pass.header">Header</a>
         </h6>
 <pre class="programlisting"><span class="comment">// forwards to <boost/spirit/repository/home/qi/primitive/flush_multi_pass.hpp>
 </span><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">spirit</span><span class="special">/</span><span class="identifier">repository</span><span class="special">/</span><span class="identifier">include</span><span class="special">/</span><span class="identifier">qi_flush_multi_pass</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
 </pre>
 <a name="spirit_repository.qi_components.primitive.flush_multi_pass.synopsis"></a><h6>
-<a name="id2694289"></a>
+<a name="id3143143"></a>
           <a class="link" href="flush_multi_pass.html#spirit_repository.qi_components.primitive.flush_multi_pass.synopsis">Synopsis</a>
         </h6>
 <pre class="programlisting"><span class="identifier">flush_multi_pass</span>
 </pre>
 <a name="spirit_repository.qi_components.primitive.flush_multi_pass.parameters"></a><h6>
-<a name="id2694324"></a>
+<a name="id3143177"></a>
           <a class="link" href="flush_multi_pass.html#spirit_repository.qi_components.primitive.flush_multi_pass.parameters">Parameters</a>
         </h6>
 <p>
@@ -74,7 +74,7 @@
           not require any parameters.
         </p>
 <a name="spirit_repository.qi_components.primitive.flush_multi_pass.attribute"></a><h6>
-<a name="id2694362"></a>
+<a name="id3143215"></a>
           <a class="link" href="flush_multi_pass.html#spirit_repository.qi_components.primitive.flush_multi_pass.attribute">Attribute</a>
         </h6>
 <p>
@@ -84,7 +84,7 @@
 <pre class="programlisting"><span class="identifier">flush_multi_pass</span> <span class="special">--></span> <span class="identifier">unused</span>
 </pre>
 <a name="spirit_repository.qi_components.primitive.flush_multi_pass.example"></a><h6>
-<a name="id2694434"></a>
+<a name="id3143287"></a>
           <a class="link" href="flush_multi_pass.html#spirit_repository.qi_components.primitive.flush_multi_pass.example">Example</a>
         </h6>
 <p>
@@ -96,7 +96,7 @@
           a function prototype (for the full example code see here: flush_multi_pass.cpp)
         </p>
 <a name="spirit_repository.qi_components.primitive.flush_multi_pass.prerequisites"></a><h6>
-<a name="id2694483"></a>
+<a name="id3143336"></a>
           <a class="link" href="flush_multi_pass.html#spirit_repository.qi_components.primitive.flush_multi_pass.prerequisites">Prerequisites</a>
         </h6>
 <p>
@@ -133,7 +133,7 @@
 <p>
         </p>
 <a name="spirit_repository.qi_components.primitive.flush_multi_pass.clearing_the_internal_buffer"></a><h6>
-<a name="id2694760"></a>
+<a name="id3143614"></a>
           <a class="link" href="flush_multi_pass.html#spirit_repository.qi_components.primitive.flush_multi_pass.clearing_the_internal_buffer">Clearing
           the internal buffer</a>
         </h6>
Modified: trunk/libs/spirit/repository/doc/karma.qbk
==============================================================================
--- trunk/libs/spirit/repository/doc/karma.qbk	(original)
+++ trunk/libs/spirit/repository/doc/karma.qbk	2009-08-14 12:39:56 EDT (Fri, 14 Aug 2009)
@@ -10,7 +10,7 @@
 
 [/include        karma/primitive_generators.qbk]
 [include        karma/directives.qbk]
-[/include        karma/nonterminals.qbk]
+[include        karma/nonterminals.qbk]
 [/include        karma/compound_generators.qbk]
 
 [endsect]
Added: trunk/libs/spirit/repository/doc/karma/nonterminals.qbk
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/repository/doc/karma/nonterminals.qbk	2009-08-14 12:39:56 EDT (Fri, 14 Aug 2009)
@@ -0,0 +1,11 @@
+[/==============================================================================
+    Copyright (C) 2001-2009 Joel de Guzman
+    Copyright (C) 2001-2009 Hartmut Kaiser
+
+    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)
+===============================================================================/]
+
+[section:nonterminal Karma Generator Non-terminals]
+[include        subrule.qbk]
+[endsect]
Added: trunk/libs/spirit/repository/doc/karma/subrule.qbk
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/repository/doc/karma/subrule.qbk	2009-08-14 12:39:56 EDT (Fri, 14 Aug 2009)
@@ -0,0 +1,209 @@
+[/==============================================================================
+    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)
+===============================================================================/]
+
+[section:subrule Karma subrules]
+
+[heading Description]
+
+The __karma__ `subrule` is a component allowing to create a named generator, and
+to refer to it by name -- much like rules and grammars. It is in fact a fully
+static version of the rule.
+
+The strength of subrules is performance. Replacing some rules with subrules
+can make a generator slightly faster (see
+[link spirit_repository.karma_components.nonterminal.subrule.performance Performance]
+below for measurements). The reason is that subrules allow aggressive inlining
+by the C++ compiler, whereas the implementation of rules is based on a virtual
+function call which, depending on the compiler, can have some run-time overhead
+and stop inlining.
+
+The weaknesses of subrules are:
+
+* subrules can only be defined and used within the same generator expression. A
+  subrule cannot be defined at one location, and then used in another location.
+* subrules put a massive strain on the C++ compiler. They increase compile
+  times and memory usage during compilation, and also increase the risk of
+  hitting compiler limits and/or bugs.
+
+[import ../../example/karma/calc2_ast_dump_sr.cpp]
+
+[calc2_ast_dump_sr_def]
+
+The example above can be found here: [@../../example/karma/mini_xml_karma_sr.cpp]
+
+As shown in this code snippet (an extract from the mini_xml_karma_sr example),
+subrules can be freely mixed with rules and grammars. Here, a group of
+3 subrules (`ast_node`, `binary_node`, `unary_node`) is assigned to a rule (named
+`entry`). This means that parts of a generator can use subrules (typically
+the innermost, most performance-critical parts), whereas the rest can use
+rules and grammars.
+
+[heading Header]
+
+    // forwards to <boost/spirit/repository/home/karma/nonterminal/subrule.hpp>
+    #include <boost/spirit/repository/include/karma_subrule.hpp>
+
+[heading Synopsis (declaration)]
+
+    subrule<ID, A1, A2, A3> sr(name);
+
+[heading Parameters (declaration)]
+
+[table
+    [[Parameter]            [Description]]
+    [[`ID`]                 [Required numeric argument. Gives the subrule
+                             a unique 'identification tag'.]]
+    [[`A1`, `A2`, `A3`]     [Optional types, can be specified in any order.
+                             Can be one of 1. signature, 2. locals, 3. delimiter
+                             (see rules reference for more information on
+                             those parameters).]]
+    [[`name`]               [Optional string. Gives the subrule a name,
+                             useful for debugging and error handling.]]
+]
+
+[heading Synopsis (usage)]
+
+Subrules are defined and used within groups, typically (and by convention)
+enclosed inside parentheses.
+
+    // Group containing N subrules
+    (
+        sr1 = expr1
+      , sr2 = expr2
+      , ... // Any number of subrules
+    }
+
+The IDs of all subrules defined within the same group must be different. It is
+an error to define several subrules with the same ID (or to define the same
+subrule multiple times) in the same group.
+
+    // Auto-subrules and inherited attributes
+    (
+        srA %= exprA << srB << srC(c1, c2, ...) // Arguments to subrule srC
+      , srB %= exprB
+      , srC  = exprC
+      , ...
+    )(a1, a2, ...)         // Arguments to group, i.e. to start subrule srA
+
+[heading Parameters (usage)]
+
+[table
+    [[Parameter]            [Description]]
+    [[`sr1`, `sr2`]         [Subrules with different IDs.]]
+    [[`expr1`, `expr2`]     [Generator expressions. Can include `sr1` and `sr2`,
+                             as well as any other valid generator expressions.]]
+    [[`srA`]                [Subrule with a synthesized attribute and inherited
+                             attributes.]]
+    [[`srB`]                [Subrule with a synthesized attribute.]]
+    [[`srC`]                [Subrule with inherited attributes.]]
+    [[`exprA`, `exprB`, `exprC`]
+                            [Generator expressions.]]
+    [[`a1`, `a2`]           [Arguments passed to the subrule group. They are
+                             passed as inherited attributes to the group's
+                             start subrule, `srA`.]]
+    [[`c1`, `c2`]           [Arguments passed as inherited attributes to
+                             subrule `srC`.]]
+]
+
+[heading Groups]
+
+A subrule group (a set of subrule definitions) is a generator, which can be
+used anywhere in a generator expression (in assignments to rules, as well as
+directly in arguments to functions such as `generate`).
+In a group, generation proceeds from the start subrule, which is the first
+(topmost) subrule defined in that group. In the two groups in the synopsis
+above, `sr1` and `srA` are the start subrules respectively -- for example
+when the first subrule group is called forth, the `sr1` subrule is called.
+
+A subrule can only be used in a group which defines it. Groups can be viewed
+as scopes: a definition of a subrule is limited to its enclosing group.
+
+    rule<outiter_type> r1, r2, r3;
+    subrule<1> sr1;
+    subrule<2> sr2;
+
+    r1 =
+            ( sr1 = 'a' << space )      // First group in r1.
+        <<  ( sr2 = +sr1 )              // Second group in r1.
+        //           ^^^
+        // DOES NOT COMPILE: sr1 is not defined in this
+        // second group, it cannot be used here (its
+        // previous definition is out of scope).
+    ;
+
+    r2 =
+            ( sr1 = 'a' << space )      // Only group in r2.
+        <<  sr1
+        //  ^^^
+        // DOES NOT COMPILE: not in a subrule group,
+        // sr1 cannot be used here (here too, its
+        // previous definition is out of scope).
+    ;
+
+    r3 =
+            ( sr1 = space << 'x' )      // Another group. The same subrule `sr1`
+                                        // can have another, independent
+                                        // definition in this group.
+    ;
+
+[heading Attributes]
+
+A subrule has the same behavior as a rule with respect to attributes. In
+particular:
+
+* the type of its synthesized attribute is the one specified in the
+  subrule's signature, if any. Otherwise it is `unused_type`.
+* the types of its inherited attributes are the ones specified in the
+  subrule's signature, if any. Otherwise the subrule has no inherited
+  attributes.
+* an auto-subrule can be defined by assigning it with the `%=` syntax.
+  In this case, the subrule's synthesized attribute is automatically
+  propagated to the RHS generator's attribute.
+* the Phoenix placeholders `_val`, `_r1`, `_r2`, ... are available to
+  refer to the subrule's synthesized and inherited attributes, if present.
+
+[heading Locals]
+
+A subrule has the same behavior as a rule with respect to locals. In
+particular, the Phoenix placeholders `_a`, `_b`, ... are available to
+refer to the subrule's locals, if present.
+
+[heading Example]
+
+[import ../../example/karma/mini_xml_karma_sr.cpp]
+
+Some includes:
+
+[mini_xml_karma_sr_includes]
+
+Some using declarations:
+
+[mini_xml_karma_sr_using]
+
+A grammar containing only one rule, defined with a group of 2 subrules:
+
+[mini_xml_karma_sr_grammar]
+
+The definitions of the `mini_xml` and `mini_xml_node` data structures
+are not shown here. The full example above can be found here:
+[@../../example/karma/mini_xml_karma_sr.cpp]
+
+[heading Performance]
+
+For comparison of run-time and compile-time performance when using subrules,
+please see the
+[link spirit_repository.qi_components.nonterminal.subrule.performance Performance]
+section of __qi__ subrules (the implementation of __karma__ and __qi__ subrules
+is very similar, so performance is very similar too).
+
+[heading Notes]
+
+FIXME add compiler-specific bit (MSVC pragmas, g++ option)
+
+[endsect]
Modified: trunk/libs/spirit/repository/doc/qi/subrule.qbk
==============================================================================
--- trunk/libs/spirit/repository/doc/qi/subrule.qbk	(original)
+++ trunk/libs/spirit/repository/doc/qi/subrule.qbk	2009-08-14 12:39:56 EDT (Fri, 14 Aug 2009)
@@ -11,8 +11,8 @@
 
 [heading Description]
 
-The __qi__ `subrule` is a component allowing to create a named parser, and to
-refer to it by name -- much like rules and grammars. It is in fact a fully
+The __qi__ `subrule` is a component allowing to create a named parser, and
+to refer to it by name -- much like rules and grammars. It is in fact a fully
 static version of the rule.
 
 The strength of subrules is performance. Replacing some rules with subrules
@@ -33,7 +33,7 @@
 
 [import ../../example/qi/calc1_sr.cpp]
 
-[subrules_def]
+[calc1_sr_def]
 
 The example above can be found here: [@../../example/qi/calc1_sr.cpp]
 
@@ -204,12 +204,13 @@
 [[Example] [Compiler]
     [Speed (run-time)] [Time (compile-time)] [Memory (compile-time)]]
 
-[[calc1_sr]      [gcc 4.4.1]              [ +6%] [ n/a] [ n/a]]
-[[calc1_sr]      [Visual C++ 2008 (VC9)]  [ +5%] [ n/a] [ n/a]]
-[[mini_xml2_sr]  [gcc 3.4.6]              [ -1%] [+54%] [+32%]]
-[[mini_xml2_sr]  [gcc 4.1.2]              [ +5%] [+58%] [+25%]]
-[[mini_xml2_sr]  [gcc 4.4.1]              [ +8%] [+20%] [+14%]]
-[[mini_xml2_sr]  [Visual C++ 2008 (VC9)]  [ +9%] [+52%] [+40%]]
+[[calc1_sr]      [gcc 4.4.1]                  [ +6%] [ n/a] [ n/a]]
+[[calc1_sr]      [Visual C++ 2008 (VC9)]      [ +5%] [ n/a] [ n/a]]
+[[mini_xml2_sr]  [gcc 3.4.6]                  [ -1%] [+54%] [+32%]]
+[[mini_xml2_sr]  [gcc 4.1.2]                  [ +5%] [+58%] [+25%]]
+[[mini_xml2_sr]  [gcc 4.4.1]                  [ +8%] [+20%] [+14%]]
+[[mini_xml2_sr]  [Visual C++ 2005 (VC8) SP1]  [ +1%] [+33%] [+27%]]
+[[mini_xml2_sr]  [Visual C++ 2008 (VC9)]      [ +9%] [+52%] [+40%]]
 
 ]
 
Modified: trunk/libs/spirit/repository/example/karma/Jamfile
==============================================================================
--- trunk/libs/spirit/repository/example/karma/Jamfile	(original)
+++ trunk/libs/spirit/repository/example/karma/Jamfile	2009-08-14 12:39:56 EDT (Fri, 14 Aug 2009)
@@ -12,4 +12,6 @@
     ;
 
 exe karma_confix : confix.cpp ;
+exe calc2_ast_dump_sr : calc2_ast_dump_sr.cpp ;
+exe mini_xml_karma_sr : mini_xml_karma_sr.cpp ;
 
Added: trunk/libs/spirit/repository/example/karma/calc2_ast_dump_sr.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/repository/example/karma/calc2_ast_dump_sr.cpp	2009-08-14 12:39:56 EDT (Fri, 14 Aug 2009)
@@ -0,0 +1,181 @@
+/*=============================================================================
+    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)
+=============================================================================*/
+///////////////////////////////////////////////////////////////////////////////
+//
+//  A Calculator example demonstrating generation of AST which gets dumped into
+//  a human readable format afterwards.
+//
+//  [ JDG April 28, 2008 ]
+//  [ HK April 28, 2008 ]
+//
+///////////////////////////////////////////////////////////////////////////////
+#include <boost/config/warning_disable.hpp>
+
+#include <iostream>
+#include <vector>
+#include <string>
+
+#include "calc2_ast.hpp"
+
+#include <boost/spirit/include/qi.hpp>
+#include <boost/spirit/include/karma.hpp>
+#include <boost/spirit/repository/include/karma_subrule.hpp>
+#include <boost/fusion/include/adapt_struct.hpp>
+
+using namespace boost::spirit;
+using namespace boost::spirit::ascii;
+namespace repo = boost::spirit::repository;
+
+///////////////////////////////////////////////////////////////////////////////
+//  Our calculator parser grammar
+///////////////////////////////////////////////////////////////////////////////
+template <typename Iterator>
+struct calculator 
+  : qi::grammar<Iterator, expression_ast(), space_type>
+{
+    calculator() : calculator::base_type(expression)
+    {
+        expression =
+            term                            [_val = _1]
+            >> *(   ('+' >> term            [_val += _1])
+                |   ('-' >> term            [_val -= _1])
+                )
+            ;
+
+        term =
+            factor                          [_val = _1]
+            >> *(   ('*' >> factor          [_val *= _1])
+                |   ('/' >> factor          [_val /= _1])
+                )
+            ;
+
+        factor =
+            uint_                           [_val = _1]
+            |   '(' >> expression           [_val = _1] >> ')'
+            |   ('-' >> factor              [_val = neg(_1)])
+            |   ('+' >> factor              [_val = pos(_1)])
+            ;
+    }
+
+    qi::rule<Iterator, expression_ast(), space_type> expression, term, factor;
+};
+
+// We need to tell fusion about our binary_op and unary_op structs
+// to make them a first-class fusion citizen
+//
+// Note: we register the members exactly in the same sequence as we need them 
+//       in the grammar
+BOOST_FUSION_ADAPT_STRUCT(
+    binary_op,
+    (expression_ast, left)
+    (char, op)
+    (expression_ast, right)
+)
+
+BOOST_FUSION_ADAPT_STRUCT(
+    unary_op,
+    (char, op)
+    (expression_ast, right)
+)
+
+///////////////////////////////////////////////////////////////////////////////
+//  Our AST grammar for the generator, this just dumps the AST as a expression
+///////////////////////////////////////////////////////////////////////////////
+template <typename OuputIterator>
+struct dump_ast
+  : karma::grammar<OuputIterator, expression_ast(), space_type>
+{
+    dump_ast() : dump_ast::base_type(entry)
+    {
+        //[calc2_ast_dump_sr_def
+        entry %= (
+            ast_node %= int_ | binary_node | unary_node
+
+          , binary_node %= '(' << ast_node << char_ << ast_node << ')'
+
+          , unary_node %= '(' << char_ << ast_node << ')'
+        );
+        //]
+    }
+
+    karma::rule<OuputIterator, expression_ast(), space_type> entry;
+
+    repo::karma::subrule<0, expression_ast(), space_type> ast_node;
+    repo::karma::subrule<1, binary_op(), space_type> binary_node;
+    repo::karma::subrule<2, unary_op(), space_type> unary_node;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+//  Main program
+///////////////////////////////////////////////////////////////////////////////
+int
+main()
+{
+    std::cout << "/////////////////////////////////////////////////////////\n\n";
+    std::cout << "Dump AST's for simple expressions...\n\n";
+    std::cout << "/////////////////////////////////////////////////////////\n\n";
+    std::cout << "Type an expression...or [q or Q] to quit\n\n";
+
+    //  Our parser grammar definitions
+    typedef std::string::const_iterator iterator_type;
+    typedef calculator<iterator_type> calculator;
+
+    calculator calc; 
+
+    // Our generator grammar definitions
+    typedef std::back_insert_iterator<std::string> output_iterator_type;
+    typedef dump_ast<output_iterator_type> dump_ast;
+
+    dump_ast ast_grammar;
+
+    std::string str;
+    while (std::getline(std::cin, str))
+    {
+        if (str.empty() || str[0] == 'q' || str[0] == 'Q')
+            break;
+
+        expression_ast ast;
+        std::string::const_iterator iter = str.begin();
+        std::string::const_iterator end = str.end();
+        bool r = qi::phrase_parse(iter, end, calc, space, ast);
+
+        if (r && iter == end)
+        {
+            std::string generated;
+            output_iterator_type outit(generated);
+            r = karma::generate_delimited(outit, ast_grammar, space, ast);
+
+            if (r)
+            {
+                std::cout << "Got AST:" << std::endl << generated 
+                          << std::endl;
+                std::cout << "-------------------------\n";
+            }
+            else
+            {
+                std::cout << "-------------------------\n";
+                std::cout << "Generating failed\n";
+                std::cout << "-------------------------\n";
+            }
+        }
+        else
+        {
+            std::string rest(iter, end);
+            std::cout << "-------------------------\n";
+            std::cout << "Parsing failed\n";
+            std::cout << "stopped at: \": " << rest << "\"\n";
+            std::cout << "-------------------------\n";
+        }
+    }
+
+    std::cout << "Bye... :-) \n\n";
+    return 0;
+}
+
+
Added: trunk/libs/spirit/repository/example/karma/mini_xml_karma_sr.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/repository/example/karma/mini_xml_karma_sr.cpp	2009-08-14 12:39:56 EDT (Fri, 14 Aug 2009)
@@ -0,0 +1,237 @@
+/*=============================================================================
+    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)
+=============================================================================*/
+///////////////////////////////////////////////////////////////////////////////
+//
+//  A mini XML-like parser, Karma is used to print out the generated AST
+//
+//  [ JDG March 25, 2007 ]   spirit2
+//  [ HK April 02, 2007  ]   spirit2
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include <boost/config/warning_disable.hpp>
+
+#include <boost/spirit/include/qi.hpp>
+//[mini_xml_karma_sr_includes
+#include <boost/spirit/include/karma.hpp>
+#include <boost/spirit/repository/include/karma_subrule.hpp>
+#include <boost/spirit/include/phoenix_core.hpp>
+#include <boost/spirit/include/phoenix_operator.hpp>
+#include <boost/spirit/include/phoenix_fusion.hpp>
+//]
+#include <boost/spirit/include/phoenix_function.hpp>
+#include <boost/spirit/include/phoenix_stl.hpp>
+#include <boost/fusion/include/adapt_struct.hpp>
+#include <boost/variant/recursive_variant.hpp>
+
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <vector>
+
+//[mini_xml_karma_sr_using
+using namespace boost::spirit;
+using namespace boost::spirit::ascii;
+namespace repo = boost::spirit::repository;
+//]
+
+namespace fusion = boost::fusion;
+namespace phoenix = boost::phoenix;
+
+using phoenix::at_c;
+using phoenix::push_back;
+
+///////////////////////////////////////////////////////////////////////////////
+//  Our mini XML tree representation
+///////////////////////////////////////////////////////////////////////////////
+struct mini_xml;
+
+typedef
+    boost::variant<
+        boost::recursive_wrapper<mini_xml>
+      , std::string
+    >
+mini_xml_node;
+
+struct mini_xml
+{
+    std::string name;                           // tag name
+    std::vector<mini_xml_node> children;        // children
+};
+
+// We need to tell fusion about our mini_xml struct
+// to make it a first-class fusion citizen
+BOOST_FUSION_ADAPT_STRUCT(
+    mini_xml,
+    (std::string, name)
+    (std::vector<mini_xml_node>, children)
+)
+
+///////////////////////////////////////////////////////////////////////////////
+//  Our mini XML grammar definition
+///////////////////////////////////////////////////////////////////////////////
+template <typename Iterator>
+struct mini_xml_parser :
+    qi::grammar<Iterator, mini_xml(), space_type>
+{
+    mini_xml_parser() : mini_xml_parser::base_type(xml)
+    {
+        text = lexeme[+(char_ - '<')        [_val += _1]];
+        node = (xml | text)                 [_val = _1];
+
+        start_tag =
+                '<'
+            >>  !lit('/')
+            >>  lexeme[+(char_ - '>')       [_val += _1]]
+            >>  '>'
+        ;
+
+        end_tag =
+                "</"
+            >>  lit(_r1)
+            >>  '>'
+        ;
+
+        xml =
+                start_tag                   [at_c<0>(_val) = _1]
+            >>  *node                       [push_back(at_c<1>(_val), _1)]
+            >>  end_tag(at_c<0>(_val))
+        ;
+    }
+
+    qi::rule<Iterator, mini_xml(), space_type> xml;
+    qi::rule<Iterator, mini_xml_node(), space_type> node;
+    qi::rule<Iterator, std::string(), space_type> text;
+    qi::rule<Iterator, std::string(), space_type> start_tag;
+    qi::rule<Iterator, void(std::string), space_type> end_tag;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+//  A couple of phoenix functions helping to access the elements of the 
+//  generated AST
+///////////////////////////////////////////////////////////////////////////////
+template <typename T>
+struct get_element
+{
+    template <typename T1>
+    struct result { typedef T const& type; };
+
+    T const& operator()(mini_xml_node const& node) const
+    {
+        return boost::get<T>(node);
+    }
+};
+
+phoenix::function<get_element<std::string> > _string;
+phoenix::function<get_element<mini_xml> > _xml;
+
+///////////////////////////////////////////////////////////////////////////////
+//  The output grammar defining the format of the generated data
+///////////////////////////////////////////////////////////////////////////////
+//[mini_xml_karma_sr_grammar
+template <typename OutputIterator>
+struct mini_xml_generator
+  : karma::grammar<OutputIterator, mini_xml()>
+{
+    mini_xml_generator() : mini_xml_generator::base_type(entry)
+    {
+        //[mini_xml_karma_sr_def
+        entry %= (
+            xml = 
+                    '<'  << string[_1 = at_c<0>(_val)] << '>'
+                <<         (*node)[_1 = at_c<1>(_val)]
+                <<  "</" << string[_1 = at_c<0>(_val)] << '>'
+
+          , node %= string | xml
+        );
+        //]
+    }
+
+    karma::rule<OutputIterator, mini_xml()> entry;
+
+    repo::karma::subrule<0, mini_xml()> xml;
+    repo::karma::subrule<1, mini_xml_node()> node;
+};
+//]
+
+///////////////////////////////////////////////////////////////////////////////
+//  Main program
+///////////////////////////////////////////////////////////////////////////////
+int main(int argc, char **argv)
+{
+    char const* filename;
+    if (argc > 1)
+    {
+        filename = argv[1];
+    }
+    else
+    {
+        std::cerr << "Error: No input file provided." << std::endl;
+        return 1;
+    }
+
+    std::ifstream in(filename, std::ios_base::in);
+
+    if (!in)
+    {
+        std::cerr << "Error: Could not open input file: "
+            << filename << std::endl;
+        return 1;
+    }
+
+    std::string storage; // We will read the contents here.
+    in.unsetf(std::ios::skipws); // No white space skipping!
+    std::copy(
+        std::istream_iterator<char>(in),
+        std::istream_iterator<char>(),
+        std::back_inserter(storage));
+
+    typedef mini_xml_parser<std::string::const_iterator> mini_xml_parser;
+    mini_xml_parser xmlin;  //  Our grammar definition
+    mini_xml ast; // our tree
+
+    std::string::const_iterator iter = storage.begin();
+    std::string::const_iterator end = storage.end();
+    bool r = qi::phrase_parse(iter, end, xmlin, space, ast);
+
+    if (r && iter == end)
+    {
+        std::cout << "-------------------------\n";
+        std::cout << "Parsing succeeded\n";
+        std::cout << "-------------------------\n";
+
+        typedef std::back_insert_iterator<std::string> outiter_type;
+        typedef mini_xml_generator<outiter_type> mini_xml_generator;
+
+        mini_xml_generator xmlout;                 //  Our grammar definition
+
+        std::string generated;
+        outiter_type outit(generated);
+        bool r = karma::generate(outit, xmlout, ast);
+
+        if (r)
+            std::cout << generated << std::endl;
+        return 0;
+    }
+    else
+    {
+        std::string::const_iterator begin = storage.begin();
+        std::size_t dist = std::distance(begin, iter);
+        std::string::const_iterator some = 
+            iter + (std::min)(storage.size()-dist, std::size_t(30));
+        std::string context(iter, some);
+        std::cout << "-------------------------\n";
+        std::cout << "Parsing failed\n";
+        std::cout << "stopped at: \": " << context << "...\"\n";
+        std::cout << "-------------------------\n";
+        return 1;
+    }
+}
+
+
Modified: trunk/libs/spirit/repository/example/qi/calc1_sr.cpp
==============================================================================
--- trunk/libs/spirit/repository/example/qi/calc1_sr.cpp	(original)
+++ trunk/libs/spirit/repository/example/qi/calc1_sr.cpp	2009-08-14 12:39:56 EDT (Fri, 14 Aug 2009)
@@ -37,7 +37,7 @@
         {
             using qi::uint_;
 
-            //[subrules_def
+            //[calc1_sr_def
             entry = (
                 expression =
                     term
Modified: trunk/libs/spirit/repository/test/CMakeLists.txt
==============================================================================
--- trunk/libs/spirit/repository/test/CMakeLists.txt	(original)
+++ trunk/libs/spirit/repository/test/CMakeLists.txt	2009-08-14 12:39:56 EDT (Fri, 14 Aug 2009)
@@ -25,4 +25,5 @@
 
 # run Karma repository tests
 boost_test_run(karma_repo_confix karma/confix.cpp COMPILE_FLAGS ${test_compile_flags})
+boost_test_run(karma_repo_subrule karma/subrule.cpp COMPILE_FLAGS ${test_compile_flags})
 
Modified: trunk/libs/spirit/repository/test/Jamfile
==============================================================================
--- trunk/libs/spirit/repository/test/Jamfile	(original)
+++ trunk/libs/spirit/repository/test/Jamfile	2009-08-14 12:39:56 EDT (Fri, 14 Aug 2009)
@@ -28,6 +28,7 @@
 
     # run Karma repository tests
     [ run karma/confix.cpp                  : : : : karma_repo_confix ]
+    [ run karma/subrule.cpp                 : : : : karma_repo_subrule ]
 
     ;
 }
Added: trunk/libs/spirit/repository/test/karma/subrule.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/repository/test/karma/subrule.cpp	2009-08-14 12:39:56 EDT (Fri, 14 Aug 2009)
@@ -0,0 +1,209 @@
+//  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)
+
+#include <boost/config/warning_disable.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+#include <boost/spirit/include/karma_operator.hpp>
+#include <boost/spirit/include/karma_char.hpp>
+#include <boost/spirit/include/karma_auxiliary.hpp>
+#include <boost/spirit/include/karma_string.hpp>
+#include <boost/spirit/include/karma_numeric.hpp>
+#include <boost/spirit/include/karma_nonterminal.hpp>
+#include <boost/spirit/include/karma_action.hpp>
+#include <boost/spirit/include/phoenix_core.hpp>
+#include <boost/spirit/include/phoenix_operator.hpp>
+#include <boost/spirit/include/phoenix_statement.hpp>
+#include <boost/spirit/include/phoenix_fusion.hpp>
+
+#include <boost/spirit/repository/include/karma_subrule.hpp>
+
+#include "test.hpp"
+
+using namespace spirit_test;
+
+///////////////////////////////////////////////////////////////////////////////
+int main()
+{
+    using namespace boost;
+    using namespace boost::spirit;
+    using namespace boost::spirit::karma;
+    using namespace boost::spirit::ascii;
+    using boost::spirit::repository::karma::subrule;
+
+    typedef spirit_test::output_iterator<char>::type outiter_type;
+
+    // basic tests
+    {
+        rule<outiter_type> start;
+        subrule<0> sr;
+
+        start = (
+            sr = char_[_1 = 'a'] << int_[_1 = 10] << double_[_1 = 12.4]
+        );
+        BOOST_TEST(test("a1012.4", start));
+
+        BOOST_TEST(test("a1012.4", (
+            sr = (char_ << int_ << double_)[_1 = 'a', _2 = 10, _3 = 12.4]
+        )));
+
+        subrule<1> a;
+        subrule<2> b;
+        subrule<3> c;
+
+        start = (
+            sr = a << b << c
+          , a = char_[_1 = 'a']
+          , b = int_[_1 = 10]
+          , c = double_[_1 = 12.4]
+        );
+        BOOST_TEST(test("a1012.4", start));
+    }
+
+    // basic tests with delimiter
+    {
+        rule<outiter_type, space_type> start;
+        subrule<0, space_type> sr;
+
+        start = (
+            sr = char_[_1 = 'a'] << int_[_1 = 10] << double_[_1 = 12.4]
+        );
+        BOOST_TEST(test_delimited("a 10 12.4 ", start, space));
+
+        BOOST_TEST(test_delimited("a 10 12.4 ", (
+            sr = (char_ << int_ << double_)[_1 = 'a', _2 = 10, _3 = 12.4]
+        ), space));
+
+        subrule<1, space_type> a;
+        subrule<2, space_type> b;
+        subrule<3, space_type> c;
+
+        start = (
+            sr = a << b << c
+          , a = char_[_1 = 'a']
+          , b = int_[_1 = 10]
+          , c = double_[_1 = 12.4]
+        );
+        BOOST_TEST(test_delimited("a 10 12.4 ", start, space));
+    }
+
+    // basic tests involving a direct parameter
+    {
+        typedef variant<char, int, double> var_type;
+
+        rule<outiter_type, var_type()> start;
+        subrule<0, var_type()> sr;
+
+        start = (
+            sr = (char_ | int_ | double_)[_1 = _r0]
+        )[_1 = _val];
+
+        var_type v ('a');
+        BOOST_TEST(test("a", start, v));
+        v = 10;
+        BOOST_TEST(test("10", start, v));
+        v = 12.4;
+        BOOST_TEST(test("12.4", start, v));
+    }
+
+    {
+        typedef variant<char, int, double> var_type;
+
+        rule<outiter_type, space_type, var_type()> start;
+        subrule<0, space_type, var_type()> sr;
+
+        start %= (
+            sr = (char_ | int_ | double_)[_1 = _r0]
+        );
+
+        var_type v ('a');
+        BOOST_TEST(test_delimited("a ", start, v, space));
+        v = 10;
+        BOOST_TEST(test_delimited("10 ", start, v, space));
+        v = 12.4;
+        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;
+
+        start = (
+            sr = char_[_1 = _r1] << int_[_1 = _r2] << double_[_1 = _r3]
+        )(_r1, _r2, _r3);
+        BOOST_TEST(test("a1012.4", start('a', 10, 12.4)));
+
+        BOOST_TEST(test("a1012.4", (
+            sr = (char_ << int_ << double_)[_1 = _r1, _2 = _r2, _3 = _r3]
+        )('a', 10, 12.4)));
+
+        subrule<1, void(char, int, double)> entry;
+        subrule<2, void(char)> a;
+        subrule<3, void(int)> b;
+        subrule<4, void(double)> c;
+
+        start = (
+            entry = a(_r1) << b(_r2) << c(_r3)
+          , a = char_[_1 = _r1]
+          , b = int_[_1 = _r1]
+          , c = double_[_1 = _r1]
+        )(_r1, _r2, _r3);
+        BOOST_TEST(test("a1012.4", start('a', 10, 12.4)));
+    }
+
+    {
+        rule<outiter_type, space_type, void(char, int, double)> start;
+        subrule<0, space_type, void(char, int, double)> sr;
+
+        start = (
+            sr = char_[_1 = _r1] << int_[_1 = _r2] << double_[_1 = _r3]
+        )(_r1, _r2, _r3);
+        BOOST_TEST(test_delimited("a 10 12.4 ", start('a', 10, 12.4), space));
+
+        BOOST_TEST(test_delimited("a 10 12.4 ", (
+            sr = (char_ << int_ << double_)[_1 = _r1, _2 = _r2, _3 = _r3]
+        )('a', 10, 12.4), space));
+
+        subrule<1, space_type, void(char, int, double)> entry;
+        subrule<2, space_type, void(char)> a;
+        subrule<3, space_type, void(int)> b;
+        subrule<4, space_type, void(double)> c;
+
+        start = (
+            entry = a(_r1) << b(_r2) << c(_r3)
+          , a = char_[_1 = _r1]
+          , b = int_[_1 = _r1]
+          , c = double_[_1 = _r1]
+        )(_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-14 12:39:56 EDT (Fri, 14 Aug 2009)
@@ -281,6 +281,16 @@
             sr2 = alpha[_val = _1 + _r1 + _r2]
         )(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]
+          , sr1 = alpha[_val = _1 + _r1]
+        )(1, 2), ch));
+        BOOST_TEST(ch == 'a' + 1 + 2 + 'c' + 3);
+#endif
     }
 
     { // context (w/ reference arg) tests