Boost logo

Boost-Commit :

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">&lt;</span><span class="identifier">ol</span><span class="special">&gt;</span><span class="identifier">Some</span> <span class="identifier">text</span><span class="special">&lt;/</span><span class="identifier">ol</span><span class="special">&gt;</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 &lt;boost/spirit/repository/home/karma/directive/confix.hpp&gt;
 </span><span class="preprocessor">#include</span> <span class="special">&lt;</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">&gt;</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">&lt;&lt;</span> <span class="identifier">ast_node</span> <span class="special">&lt;&lt;</span> <span class="identifier">char_</span> <span class="special">&lt;&lt;</span> <span class="identifier">ast_node</span> <span class="special">&lt;&lt;</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">&lt;&lt;</span> <span class="identifier">char_</span> <span class="special">&lt;&lt;</span> <span class="identifier">ast_node</span> <span class="special">&lt;&lt;</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 &lt;boost/spirit/repository/home/karma/nonterminal/subrule.hpp&gt;
+</span><span class="preprocessor">#include</span> <span class="special">&lt;</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">&gt;</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">&lt;</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">&gt;</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">&lt;&lt;</span> <span class="identifier">srB</span> <span class="special">&lt;&lt;</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">&lt;</span><span class="identifier">outiter_type</span><span class="special">&gt;</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">&lt;</span><span class="number">1</span><span class="special">&gt;</span> <span class="identifier">sr1</span><span class="special">;</span>
+<span class="identifier">subrule</span><span class="special">&lt;</span><span class="number">2</span><span class="special">&gt;</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">&lt;&lt;</span> <span class="identifier">space</span> <span class="special">)</span> <span class="comment">// First group in r1.
+</span> <span class="special">&lt;&lt;</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">&lt;&lt;</span> <span class="identifier">space</span> <span class="special">)</span> <span class="comment">// Only group in r2.
+</span> <span class="special">&lt;&lt;</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">&lt;&lt;</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">&lt;</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">&gt;</span>
+<span class="preprocessor">#include</span> <span class="special">&lt;</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">&gt;</span>
+<span class="preprocessor">#include</span> <span class="special">&lt;</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">&gt;</span>
+<span class="preprocessor">#include</span> <span class="special">&lt;</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">&gt;</span>
+<span class="preprocessor">#include</span> <span class="special">&lt;</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">&gt;</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">&lt;</span><span class="keyword">typename</span> <span class="identifier">OutputIterator</span><span class="special">&gt;</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">&lt;</span><span class="identifier">OutputIterator</span><span class="special">,</span> <span class="identifier">mini_xml</span><span class="special">()&gt;</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">'&lt;'</span> <span class="special">&lt;&lt;</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">&lt;</span><span class="number">0</span><span class="special">&gt;(</span><span class="identifier">_val</span><span class="special">)]</span> <span class="special">&lt;&lt;</span> <span class="char">'&gt;'</span>
+ <span class="special">&lt;&lt;</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">&lt;</span><span class="number">1</span><span class="special">&gt;(</span><span class="identifier">_val</span><span class="special">)]</span>
+ <span class="special">&lt;&lt;</span> <span class="string">"&lt;/"</span> <span class="special">&lt;&lt;</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">&lt;</span><span class="number">0</span><span class="special">&gt;(</span><span class="identifier">_val</span><span class="special">)]</span> <span class="special">&lt;&lt;</span> <span class="char">'&gt;'</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 &lt;boost/spirit/repository/home/qi/directive/confix.hpp&gt;
 </span><span class="preprocessor">#include</span> <span class="special">&lt;</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">&gt;</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 &lt;boost/spirit/repository/home/qi/directive/distinct.hpp&gt;
 </span><span class="preprocessor">#include</span> <span class="special">&lt;</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">&gt;</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">--&gt;</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 &lt;boost/spirit/repository/home/qi/nonterminal/subrule.hpp&gt;
 </span><span class="preprocessor">#include</span> <span class="special">&lt;</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">&gt;</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">&lt;</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">&gt;</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 &lt;boost/spirit/repository/home/qi/primitive/flush_multi_pass.hpp&gt;
 </span><span class="preprocessor">#include</span> <span class="special">&lt;</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">&gt;</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">--&gt;</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


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