Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r55547 - in trunk: boost/spirit/repository/home boost/spirit/repository/home/qi boost/spirit/repository/home/qi/nonterminal boost/spirit/repository/include 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/karma_generator_directives libs/spirit/repository/doc/html/spirit_repository/qi_components 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/qi libs/spirit/repository/example/qi libs/spirit/repository/test libs/spirit/repository/test/qi
From: frabar666_at_[hidden]
Date: 2009-08-12 10:07:53


Author: fbarel
Date: 2009-08-12 10:07:46 EDT (Wed, 12 Aug 2009)
New Revision: 55547
URL: http://svn.boost.org/trac/boost/changeset/55547

Log:
Spirit: adding Qi subrules to repository
Added:
   trunk/boost/spirit/repository/home/qi/nonterminal/
   trunk/boost/spirit/repository/home/qi/nonterminal.hpp (contents, props changed)
   trunk/boost/spirit/repository/home/qi/nonterminal/subrule.hpp (contents, props changed)
   trunk/boost/spirit/repository/include/qi_nonterminal.hpp (contents, props changed)
   trunk/boost/spirit/repository/include/qi_subrule.hpp (contents, props changed)
   trunk/libs/spirit/repository/doc/html/spirit_repository/qi_components/nonterminal/
   trunk/libs/spirit/repository/doc/html/spirit_repository/qi_components/nonterminal.html (contents, props changed)
   trunk/libs/spirit/repository/doc/html/spirit_repository/qi_components/nonterminal/subrule.html (contents, props changed)
   trunk/libs/spirit/repository/doc/qi/nonterminals.qbk (contents, props changed)
   trunk/libs/spirit/repository/doc/qi/subrule.qbk (contents, props changed)
   trunk/libs/spirit/repository/example/qi/calc1_sr.cpp (contents, props changed)
   trunk/libs/spirit/repository/example/qi/mini_xml2_sr.cpp (contents, props changed)
   trunk/libs/spirit/repository/test/qi/subrule.cpp (contents, props changed)
Text files modified:
   trunk/boost/spirit/repository/home/qi.hpp | 1 +
   trunk/libs/spirit/repository/doc/html/index.html | 8 ++++++--
   trunk/libs/spirit/repository/doc/html/spirit_repository/karma_components.html | 6 +++---
   trunk/libs/spirit/repository/doc/html/spirit_repository/karma_components/karma_generator_directives/karma_confix_generator.html | 20 ++++++++++----------
   trunk/libs/spirit/repository/doc/html/spirit_repository/preface.html | 8 ++++----
   trunk/libs/spirit/repository/doc/html/spirit_repository/qi_components.html | 4 ++++
   trunk/libs/spirit/repository/doc/html/spirit_repository/qi_components/directives/confix.html | 21 +++++++++++----------
   trunk/libs/spirit/repository/doc/html/spirit_repository/qi_components/directives/distinct.html | 24 ++++++++++++------------
   trunk/libs/spirit/repository/doc/html/spirit_repository/qi_components/primitive/flush_multi_pass.html | 18 +++++++++---------
   trunk/libs/spirit/repository/doc/karma.qbk | 3 ++-
   trunk/libs/spirit/repository/doc/qi.qbk | 3 ++-
   trunk/libs/spirit/repository/example/qi/Jamfile | 8 +++++++-
   trunk/libs/spirit/repository/test/CMakeLists.txt | 1 +
   trunk/libs/spirit/repository/test/Jamfile | 1 +
   14 files changed, 73 insertions(+), 53 deletions(-)

Modified: trunk/boost/spirit/repository/home/qi.hpp
==============================================================================
--- trunk/boost/spirit/repository/home/qi.hpp (original)
+++ trunk/boost/spirit/repository/home/qi.hpp 2009-08-12 10:07:46 EDT (Wed, 12 Aug 2009)
@@ -13,6 +13,7 @@
 
 #include <boost/spirit/repository/home/qi/primitive.hpp>
 #include <boost/spirit/repository/home/qi/directive.hpp>
+#include <boost/spirit/repository/home/qi/nonterminal.hpp>
 
 #endif
 

Added: trunk/boost/spirit/repository/home/qi/nonterminal.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/repository/home/qi/nonterminal.hpp 2009-08-12 10:07:46 EDT (Wed, 12 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_QI_NONTERMINAL_AUG_12_2009_1140AM)
+#define SPIRIT_REPOSITORY_QI_NONTERMINAL_AUG_12_2009_1140AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/repository/home/qi/nonterminal/subrule.hpp>
+
+#endif
+

Added: trunk/boost/spirit/repository/home/qi/nonterminal/subrule.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/repository/home/qi/nonterminal/subrule.hpp 2009-08-12 10:07:46 EDT (Wed, 12 Aug 2009)
@@ -0,0 +1,734 @@
+/*=============================================================================
+ 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(SPIRIT_REPOSITORY_QI_SUBRULE_AUGUST_06_2009_0239AM)
+#define SPIRIT_REPOSITORY_QI_SUBRULE_AUGUST_06_2009_0239AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/qi/domain.hpp>
+#include <boost/spirit/home/qi/meta_compiler.hpp>
+#include <boost/spirit/home/qi/parser.hpp>
+#include <boost/spirit/home/qi/reference.hpp>
+#include <boost/spirit/home/qi/nonterminal/detail/parser_binder.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/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/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/size.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<qi::domain, proto::tag::comma> // enables ,
+ : mpl::true_ {};
+
+ template <>
+ struct flatten_tree<qi::domain, proto::tag::comma> // flattens ,
+ : mpl::true_ {};
+}}
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit { namespace repository { namespace qi
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // 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,
+ // - 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::qi::reference<subrule_group<Defs> const>
+ >::type
+ , subrule_group<Defs>
+ >
+ , spirit::qi::parser<subrule_group<Defs> >
+ {
+ // 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::qi::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 Iterator, typename Context
+ , typename Skipper, typename Attribute>
+ bool parse(Iterator& first, Iterator const& last
+ , Context& context, Skipper const& skipper
+ , Attribute& attr) const
+ {
+ // Forward to first subrule.
+ return parse_subrule(fusion::front(defs).second
+ , first, last, context, skipper, attr);
+ }
+
+ template <typename Iterator, typename Context
+ , typename Skipper, typename Attribute, typename Params>
+ bool parse(Iterator& first, Iterator const& last
+ , Context& context, Skipper const& skipper
+ , Attribute& attr, Params const& params) const
+ {
+ // Forward to first subrule.
+ return parse_subrule(fusion::front(defs).second
+ , first, last, context, skipper, attr, params);
+ }
+
+ template <int ID, typename Iterator, typename Context
+ , typename Skipper, typename Attribute>
+ bool parse_subrule_id(Iterator& first, Iterator const& last
+ , Context& context, Skipper const& skipper
+ , Attribute& attr) const
+ {
+ return parse_subrule(def<ID>()
+ , first, last, context, skipper, attr);
+ }
+
+ template <int ID, typename Iterator, typename Context
+ , typename Skipper, typename Attribute, typename Params>
+ bool parse_subrule_id(Iterator& first, Iterator const& last
+ , Context& context, Skipper const& skipper
+ , Attribute& attr, Params const& params) const
+ {
+ return parse_subrule(def<ID>()
+ , first, last, context, skipper, attr, params);
+ }
+
+ template <typename Def
+ , typename Iterator, typename Context
+ , typename Skipper, typename Attribute>
+ bool parse_subrule(Def const& def
+ , Iterator& first, Iterator const& last
+ , Context& /*caller_context*/, Skipper const& skipper
+ , Attribute& attr) const
+ {
+ // compute context type for this subrule
+ typedef typename Def::locals_type subrule_locals_type;
+ typedef typename Def::skipper_type subrule_skipper_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;
+
+ // prepare attribute
+ typedef
+ traits::make_attribute<subrule_attr_type, Attribute>
+ make_attribute;
+ typename make_attribute::type attr_ = make_attribute::call(attr);
+
+ // If you are seeing a compilation error here, you are probably
+ // trying to use a subrule which has inherited attributes,
+ // without passing values for them.
+ context_type context(*this, attr_);
+
+ // If you are seeing a compilation error here stating that the
+ // forth parameter can't be converted to a qi::reference
+ // then you are probably trying to use a subrule with an
+ // incompatible skipper type.
+ return call_binder<subrule_skipper_type>(
+ first, last, context, skipper, def.binder);
+ }
+
+ template <typename Def
+ , typename Iterator, typename Context
+ , typename Skipper, typename Attribute, typename Params>
+ bool parse_subrule(Def const& def
+ , Iterator& first, Iterator const& last
+ , Context& caller_context, Skipper const& skipper
+ , Attribute& attr, Params const& params) const
+ {
+ // compute context type for this subrule
+ typedef typename Def::locals_type subrule_locals_type;
+ typedef typename Def::skipper_type subrule_skipper_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;
+
+ // prepare attribute
+ typedef
+ traits::make_attribute<subrule_attr_type, Attribute>
+ make_attribute;
+ typename make_attribute::type attr_ = make_attribute::call(attr);
+
+ // If you are seeing a compilation error here, you are probably
+ // trying to use a subrule which has inherited attributes,
+ // passing values of incompatible types for them.
+ context_type context(*this, attr_, params, caller_context);
+
+ // If you are seeing a compilation error here stating that the
+ // forth parameter can't be converted to a qi::reference
+ // then you are probably trying to use a subrule with an
+ // incompatible skipper type.
+ return call_binder<subrule_skipper_type>(
+ first, last, context, skipper, def.binder);
+ }
+
+ // wrapper to let the incoming skipper be converted to the
+ // skipper type expected by the subrule being invoked
+ template <typename Skipper, typename Iterator
+ , typename Context, typename Binder>
+ bool call_binder(Iterator& first, Iterator const& last
+ , Context& context, Skipper const& skipper
+ , Binder const& binder) const
+ {
+ return binder(first, last, context, skipper);
+ }
+
+ template <typename Context>
+ info what(Context& context) const
+ {
+ // Forward to first subrule.
+ return fusion::front(defs).second.binder.p.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/qi/nonterminal/detail/fcall.hpp>
+
+ Defs defs;
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ // subrule_definition: holds one definition of a subrule
+ ///////////////////////////////////////////////////////////////////////////
+ template <
+ int ID_
+ , typename Locals
+ , typename Skipper
+ , 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 Skipper skipper_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::qi::detail::parser_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 parser.
+ ///////////////////////////////////////////////////////////////////////////
+ template <
+ int ID_
+ , typename T1 = unused_type
+ , typename T2 = unused_type
+ , typename T3 = unused_type
+ >
+ struct subrule
+ : proto::extends<
+ typename proto::terminal<
+ spirit::qi::reference<subrule<ID_, T1, T2, T3> const>
+ >::type
+ , subrule<ID_, T1, T2, T3>
+ >
+ , spirit::qi::parser<subrule<ID_, T1, T2, T3> >
+ {
+ typedef mpl::int_<ID_> id_type;
+ BOOST_STATIC_CONSTANT(int, ID = ID_);
+
+ typedef subrule<ID_, T1, T2, T3> this_type;
+ typedef spirit::qi::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 skip-parser type
+ typedef typename
+ spirit::detail::extract_component<
+ spirit::qi::domain, template_params>::type
+ skipper_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<attr_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 qi expression.
+ BOOST_SPIRIT_ASSERT_MATCH(spirit::qi::domain, Expr);
+
+ typedef typename result_of::compile<
+ spirit::qi::domain, Expr>::type subject_type;
+
+ typedef subrule_definition<
+ ID_
+ , locals_type
+ , skipper_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::qi::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::qi::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 Iterator, typename Group
+ , typename Attributes, typename Locals
+ , typename Skipper, typename Attribute>
+ bool parse(Iterator& first, Iterator const& last
+ , subrule_context<Group, Attributes, Locals>& context
+ , Skipper const& skipper, Attribute& attr) const
+ {
+ return context.group.template parse_subrule_id<ID_>(
+ first, last, context, skipper, attr);
+ }
+
+ template <typename Iterator, typename Context
+ , typename Skipper, typename Attribute>
+ bool parse(Iterator& /*first*/, Iterator const& /*last*/
+ , Context& /*context*/
+ , Skipper const& /*skipper*/, Attribute& /*attr*/) const
+ {
+ // If you are seeing a compilation error here, you are trying
+ // to use a subrule as a parser outside of a subrule group.
+ BOOST_SPIRIT_ASSERT_MSG(false
+ , subrule_used_outside_subrule_group, (id_type));
+
+ return false;
+ }
+
+ template <typename Iterator, typename Group
+ , typename Attributes, typename Locals
+ , typename Skipper, typename Attribute
+ , typename Params>
+ bool parse(Iterator& first, Iterator const& last
+ , subrule_context<Group, Attributes, Locals>& context
+ , Skipper const& skipper, Attribute& attr
+ , Params const& params) const
+ {
+ return context.group.template parse_subrule_id<ID_>(
+ first, last, context, skipper, attr, params);
+ }
+
+ template <typename Iterator, typename Context
+ , typename Skipper, typename Attribute
+ , typename Params>
+ bool parse(Iterator& /*first*/, Iterator const& /*last*/
+ , Context& /*context*/
+ , Skipper const& /*skipper*/, Attribute& /*attr*/
+ , Params const& /*params*/) const
+ {
+ // If you are seeing a compilation error here, you are trying
+ // to use a subrule as a parser 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/qi/nonterminal/detail/fcall.hpp>
+
+ std::string name_;
+ };
+}}}}
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit { namespace qi
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // Parser generators: make_xxx function (objects)
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Elements, typename Modifiers>
+ struct make_composite<proto::tag::comma, Elements, Modifiers>
+ {
+ // Elements is a Fusion sequence of reference<subrule_group<...> const>
+
+
+ ///////////////////////////////////////////////////////////////////////
+ // 1. confirm that, to avoid further confusion if it is not the case
+
+ // this check is done with a metafunction class instead of an MPL
+ // lambda expression with placeholders for the sake of gcc-3.x
+ struct is_not_subrule_group
+ {
+ template <typename T>
+ struct apply
+ {
+ typedef mpl::true_ type;
+ };
+ template <typename Defs>
+ struct apply<reference<
+ spirit::repository::qi::subrule_group<Defs> const> >
+ {
+ typedef mpl::false_ type;
+ };
+ };
+
+ // If you are seeing a compilation error here, you are using a comma
+ // (,) for something other than separating definitions of subrules.
+ BOOST_SPIRIT_ASSERT_MSG(
+ (is_same<
+ typename fusion::result_of::find_if<Elements
+ , is_not_subrule_group>::type,
+ typename fusion::result_of::end<Elements>::type>::value)
+ , comma_not_separating_subrule_definitions, (Elements));
+
+
+ ///////////////////////////////////////////////////////////////////////
+ // 2. merge subrule groups together
+
+ // function object applied on each element (reference to subrule_group)
+ // with fusion::fold to compute the map of definitions for the
+ // merged subrule_group
+ struct merge_defs
+ {
+ template <typename Element, typename State>
+ struct result_
+ {
+ // Note: it is not checked that any subrule is defined at most
+ // once within a group (i.e. that keys are unique when joining
+ // the two maps). If needed, this check could be added here.
+
+ typedef
+ typename fusion::result_of::join<
+ State const
+ , typename Element::subject_type::defs_type const
+ >::type
+ type;
+ };
+
+ template <typename Signature>
+ struct result;
+ template <typename Self, typename Element, typename State>
+ struct result<Self(Element, State)>
+ : result_<
+ typename remove_reference<Element>::type
+ , typename remove_reference<State>::type> {};
+
+ template <typename Element, typename State>
+ typename result_<Element, State>::type
+ operator()(Element const& element, State const& state)
+ {
+ typedef typename
+ result_<Element, State>::type result_type;
+
+ return fusion::join(
+ state
+ , element.ref.get().defs);
+ }
+ };
+
+ typedef
+ typename fusion::result_of::fold<
+ Elements
+ , typename fusion::result_of::make_map<>::type
+ , merge_defs>::type
+ merged_defs_type;
+
+ typedef typename
+ fusion::result_of::as_map<merged_defs_type>::type defs_type;
+
+
+ typedef spirit::repository::qi::subrule_group<
+ defs_type> result_type;
+
+ result_type operator()(Elements const& elements, unused_type) const
+ {
+ return result_type(
+ fusion::as_map(
+ fusion::fold(
+ elements
+ , fusion::make_map()
+ , merge_defs())));
+ }
+ };
+}}}
+
+#if defined(BOOST_MSVC)
+# pragma warning(pop)
+#endif
+
+#endif

Added: trunk/boost/spirit/repository/include/qi_nonterminal.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/repository/include/qi_nonterminal.hpp 2009-08-12 10:07:46 EDT (Wed, 12 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_QI_NONTERMINAL
+#define BOOST_SPIRIT_REPOSITORY_INCLUDE_QI_NONTERMINAL
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/repository/home/qi/nonterminal.hpp>
+
+#endif

Added: trunk/boost/spirit/repository/include/qi_subrule.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/repository/include/qi_subrule.hpp 2009-08-12 10:07:46 EDT (Wed, 12 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_QI_SUBRULE
+#define BOOST_SPIRIT_REPOSITORY_INCLUDE_QI_SUBRULE
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/repository/home/qi/nonterminal/subrule.hpp>
+
+#endif

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-12 10:07:46 EDT (Wed, 12 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="id1033740"></a><p>
+<a name="id3036078"></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>
@@ -60,6 +60,10 @@
 <dt><span class="section"><a href="spirit_repository/qi_components/directives/distinct.html">
         Qi Distinct Parser Directive</a></span></dt>
 </dl></dd>
+<dt><span class="section"><a href="spirit_repository/qi_components/nonterminal.html"> Qi Parser
+ Non-terminals</a></span></dt>
+<dd><dl><dt><span class="section"><a href="spirit_repository/qi_components/nonterminal/subrule.html">
+ Qi subrules</a></span></dt></dl></dd>
 </dl></dd>
 <dt><span class="section">Karma Components</span></dt>
 <dd><dl>
@@ -72,7 +76,7 @@
 </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 02, 2009 at 01:35:55 GMT</small></p></td>
+<td align="left"><p><small>Last revised: August 12, 2009 at 13:57:16 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-12 10:07:46 EDT (Wed, 12 Aug 2009)
@@ -6,7 +6,7 @@
 <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="../index.html" title="Spirit Repository 0.1">
-<link rel="prev" href="qi_components/directives/distinct.html" title="Qi Distinct Parser Directive">
+<link rel="prev" href="qi_components/nonterminal/subrule.html" title="Qi subrules">
 <link rel="next" href="karma_components/karma_generator_directives.html" title="Karma Generator Directives">
 </head>
 <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
@@ -20,7 +20,7 @@
 </tr></table>
 <hr>
 <div class="spirit-nav">
-<a accesskey="p" href="qi_components/directives/distinct.html"><img src="../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.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="karma_components/karma_generator_directives.html"><img src="../../../../../../doc/html/images/next.png" alt="Next"></a>
+<a accesskey="p" href="qi_components/nonterminal/subrule.html"><img src="../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.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="karma_components/karma_generator_directives.html"><img src="../../../../../../doc/html/images/next.png" alt="Next"></a>
 </div>
 <div class="section" title="Karma Components">
 <div class="titlepage"><div><div><h2 class="title" style="clear: both">
@@ -44,7 +44,7 @@
 </tr></table>
 <hr>
 <div class="spirit-nav">
-<a accesskey="p" href="qi_components/directives/distinct.html"><img src="../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.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="karma_components/karma_generator_directives.html"><img src="../../../../../../doc/html/images/next.png" alt="Next"></a>
+<a accesskey="p" href="qi_components/nonterminal/subrule.html"><img src="../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.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="karma_components/karma_generator_directives.html"><img src="../../../../../../doc/html/images/next.png" alt="Next"></a>
 </div>
 </body>
 </html>

Modified: trunk/libs/spirit/repository/doc/html/spirit_repository/karma_components/karma_generator_directives/karma_confix_generator.html
==============================================================================
--- trunk/libs/spirit/repository/doc/html/spirit_repository/karma_components/karma_generator_directives/karma_confix_generator.html (original)
+++ trunk/libs/spirit/repository/doc/html/spirit_repository/karma_components/karma_generator_directives/karma_confix_generator.html 2009-08-12 10:07:46 EDT (Wed, 12 Aug 2009)
@@ -27,7 +27,7 @@
         Confix Generator</a>
 </h4></div></div></div>
 <a name="spirit_repository.karma_components.karma_generator_directives.karma_confix_generator.description"></a><h6>
-<a name="id1045040"></a>
+<a name="id3095618"></a>
           <a class="link" href="karma_confix_generator.html#spirit_repository.karma_components.karma_generator_directives.karma_confix_generator.description">Description</a>
         </h6>
 <p>
@@ -92,20 +92,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.karma_generator_directives.karma_confix_generator.header"></a><h6>
-<a name="id1045937"></a>
+<a name="id3096755"></a>
           <a class="link" href="karma_confix_generator.html#spirit_repository.karma_components.karma_generator_directives.karma_confix_generator.header">Header</a>
         </h6>
-<pre class="programlisting"><span class="comment">// forwards to &lt;boost/spirit/repository/home/karma/confix.hpp&gt;
+<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.karma_generator_directives.karma_confix_generator.synopsis"></a><h6>
-<a name="id1047107"></a>
+<a name="id3096859"></a>
           <a class="link" href="karma_confix_generator.html#spirit_repository.karma_components.karma_generator_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.karma_generator_directives.karma_confix_generator.parameters"></a><h6>
-<a name="id1047155"></a>
+<a name="id3096928"></a>
           <a class="link" href="karma_confix_generator.html#spirit_repository.karma_components.karma_generator_directives.karma_confix_generator.parameters">Parameters</a>
         </h6>
 <div class="informaltable"><table class="table">
@@ -174,7 +174,7 @@
           All three parameters can be arbitrary complex generators themselves.
         </p>
 <a name="spirit_repository.karma_components.karma_generator_directives.karma_confix_generator.attribute"></a><h6>
-<a name="id1047313"></a>
+<a name="id3097126"></a>
           <a class="link" href="karma_confix_generator.html#spirit_repository.karma_components.karma_generator_directives.karma_confix_generator.attribute">Attribute</a>
         </h6>
 <p>
@@ -201,7 +201,7 @@
           </p></td></tr>
 </table></div>
 <a name="spirit_repository.karma_components.karma_generator_directives.karma_confix_generator.example"></a><h6>
-<a name="id1047489"></a>
+<a name="id3097365"></a>
           <a class="link" href="karma_confix_generator.html#spirit_repository.karma_components.karma_generator_directives.karma_confix_generator.example">Example</a>
         </h6>
 <p>
@@ -210,7 +210,7 @@
           styles and a function prototype (for the full example code see here: confix.cpp)
         </p>
 <a name="spirit_repository.karma_components.karma_generator_directives.karma_confix_generator.prerequisites"></a><h6>
-<a name="id1047519"></a>
+<a name="id3097414"></a>
           <a class="link" href="karma_confix_generator.html#spirit_repository.karma_components.karma_generator_directives.karma_confix_generator.prerequisites">Prerequisites</a>
         </h6>
 <p>
@@ -248,7 +248,7 @@
 <p>
         </p>
 <a name="spirit_repository.karma_components.karma_generator_directives.karma_confix_generator.generating_different_comment_styles"></a><h6>
-<a name="id1047762"></a>
+<a name="id3097722"></a>
           <a class="link" href="karma_confix_generator.html#spirit_repository.karma_components.karma_generator_directives.karma_confix_generator.generating_different_comment_styles">Generating
           Different Comment Styles</a>
         </h6>
@@ -300,7 +300,7 @@
           */</span> </code>.
         </p>
 <a name="spirit_repository.karma_components.karma_generator_directives.karma_confix_generator.generating_a_function_prototype"></a><h6>
-<a name="id1048063"></a>
+<a name="id3098107"></a>
           <a class="link" href="karma_confix_generator.html#spirit_repository.karma_components.karma_generator_directives.karma_confix_generator.generating_a_function_prototype">Generating
           a Function Prototype</a>
         </h6>

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-12 10:07:46 EDT (Wed, 12 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="id1033770"></a>
+<a name="id3036119"></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="id1033859"></a>
+<a name="id3038600"></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="id1033872"></a><p class="title"><b>Table 1. Icons</b></p>
+<a name="id3038620"></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="id1034113"></a>
+<a name="id3034355"></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.html
==============================================================================
--- trunk/libs/spirit/repository/doc/html/spirit_repository/qi_components.html (original)
+++ trunk/libs/spirit/repository/doc/html/spirit_repository/qi_components.html 2009-08-12 10:07:46 EDT (Wed, 12 Aug 2009)
@@ -39,6 +39,10 @@
 <dt><span class="section"><a href="qi_components/directives/distinct.html">
         Qi Distinct Parser Directive</a></span></dt>
 </dl></dd>
+<dt><span class="section"><a href="qi_components/nonterminal.html"> Qi Parser
+ Non-terminals</a></span></dt>
+<dd><dl><dt><span class="section"><a href="qi_components/nonterminal/subrule.html">
+ Qi 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/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-12 10:07:46 EDT (Wed, 12 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="id1038203"></a>
+<a name="id3084900"></a>
           <a class="link" href="confix.html#spirit_repository.qi_components.directives.confix.description">Description</a>
         </h6>
 <p>
@@ -95,19 +95,20 @@
           </p></td></tr>
 </table></div>
 <a name="spirit_repository.qi_components.directives.confix.header"></a><h6>
-<a name="id1038971"></a>
+<a name="id3085857"></a>
           <a class="link" href="confix.html#spirit_repository.qi_components.directives.confix.header">Header</a>
         </h6>
-<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">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 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="id1039045"></a>
+<a name="id3085958"></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="id1039098"></a>
+<a name="id3086025"></a>
           <a class="link" href="confix.html#spirit_repository.qi_components.directives.confix.parameters">Parameters</a>
         </h6>
 <div class="informaltable"><table class="table">
@@ -171,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="id1039240"></a>
+<a name="id3086188"></a>
           <a class="link" href="confix.html#spirit_repository.qi_components.directives.confix.attribute">Attribute</a>
         </h6>
 <p>
@@ -197,7 +198,7 @@
           </p></td></tr>
 </table></div>
 <a name="spirit_repository.qi_components.directives.confix.example"></a><h6>
-<a name="id1039477"></a>
+<a name="id3086500"></a>
           <a class="link" href="confix.html#spirit_repository.qi_components.directives.confix.example">Example</a>
         </h6>
 <p>
@@ -207,7 +208,7 @@
           see confix.cpp)
         </p>
 <a name="spirit_repository.qi_components.directives.confix.prerequisites"></a><h6>
-<a name="id1039512"></a>
+<a name="id3086548"></a>
           <a class="link" href="confix.html#spirit_repository.qi_components.directives.confix.prerequisites">Prerequisites</a>
         </h6>
 <p>
@@ -250,7 +251,7 @@
 <p>
         </p>
 <a name="spirit_repository.qi_components.directives.confix.parsing_different_comment_styles"></a><h6>
-<a name="id1039930"></a>
+<a name="id3087070"></a>
           <a class="link" href="confix.html#spirit_repository.qi_components.directives.confix.parsing_different_comment_styles">Parsing
           Different Comment Styles</a>
         </h6>
@@ -310,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="id1041605"></a>
+<a name="id3087779"></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-12 10:07:46 EDT (Wed, 12 Aug 2009)
@@ -7,7 +7,7 @@
 <link rel="home" href="../../../index.html" title="Spirit Repository 0.1">
 <link rel="up" href="../directives.html" title="Qi Parser Directives">
 <link rel="prev" href="confix.html" title="Qi Confix Parser Directive">
-<link rel="next" href="../../karma_components.html" title="Karma Components">
+<link rel="next" href="../nonterminal.html" title="Qi Parser Non-terminals">
 </head>
 <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
 <table cellpadding="2" width="100%"><tr>
@@ -20,7 +20,7 @@
 </tr></table>
 <hr>
 <div class="spirit-nav">
-<a accesskey="p" href="confix.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="../../karma_components.html"><img src="../../../../../../../../doc/html/images/next.png" alt="Next"></a>
+<a accesskey="p" href="confix.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="Qi Distinct Parser Directive">
 <div class="titlepage"><div><div><h4 class="title">
@@ -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="id1041958"></a>
+<a name="id3088218"></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="id1043195"></a>
+<a name="id3089779"></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/distinct.hpp&gt;
+<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="id1043273"></a>
+<a name="id3089881"></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="id1043317"></a>
+<a name="id3089938"></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="id1043421"></a>
+<a name="id3090055"></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="id1043816"></a>
+<a name="id3090207"></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="id1043849"></a>
+<a name="id3090250"></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="id1044092"></a>
+<a name="id3090559"></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>
@@ -348,7 +348,7 @@
 </tr></table>
 <hr>
 <div class="spirit-nav">
-<a accesskey="p" href="confix.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="../../karma_components.html"><img src="../../../../../../../../doc/html/images/next.png" alt="Next"></a>
+<a accesskey="p" href="confix.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/qi_components/nonterminal.html
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/repository/doc/html/spirit_repository/qi_components/nonterminal.html 2009-08-12 10:07:46 EDT (Wed, 12 Aug 2009)
@@ -0,0 +1,47 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>Qi Parser 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="../qi_components.html" title="Qi Components">
+<link rel="prev" href="directives/distinct.html" title="Qi Distinct Parser Directive">
+<link rel="next" href="nonterminal/subrule.html" title="Qi 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/distinct.html"><img src="../../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../qi_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="Qi Parser Non-terminals">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="spirit_repository.qi_components.nonterminal"></a><a class="link" href="nonterminal.html" title="Qi Parser Non-terminals"> Qi Parser
+ Non-terminals</a>
+</h3></div></div></div>
+<div class="toc"><dl><dt><span class="section"><a href="nonterminal/subrule.html">
+ Qi 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/distinct.html"><img src="../../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../qi_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/qi_components/nonterminal/subrule.html
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/repository/doc/html/spirit_repository/qi_components/nonterminal/subrule.html 2009-08-12 10:07:46 EDT (Wed, 12 Aug 2009)
@@ -0,0 +1,542 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>Qi 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="Qi Parser Non-terminals">
+<link rel="prev" href="../nonterminal.html" title="Qi Parser Non-terminals">
+<link rel="next" href="../../karma_components.html" title="Karma Components">
+</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><a accesskey="n" href="../../karma_components.html"><img src="../../../../../../../../doc/html/images/next.png" alt="Next"></a>
+</div>
+<div class="section" title="Qi subrules">
+<div class="titlepage"><div><div><h4 class="title">
+<a name="spirit_repository.qi_components.nonterminal.subrule"></a><a class="link" href="subrule.html" title="Qi subrules">
+ Qi subrules</a>
+</h4></div></div></div>
+<a name="spirit_repository.qi_components.nonterminal.subrule.description"></a><h6>
+<a name="id3091713"></a>
+ <a class="link" href="subrule.html#spirit_repository.qi_components.nonterminal.subrule.description">Description</a>
+ </h6>
+<p>
+ The <span class="emphasis"><em>Spirit.Qi</em></span> <code class="computeroutput"><span class="identifier">subrule</span></code>
+ 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.
+ </p>
+<p>
+ The strength of subrules is performance. Replacing some rules with subrules
+ can make a parser faster (for example the <span class="emphasis"><em>Spirit.Qi</em></span>
+ calc1 and mini_xml2 examples, compiled with gcc-4.4, are respectively 6%
+ and 8% faster when using subrules instead of rules). 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 1. has a fixed run-time
+ overhead and 2. stops 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 parser 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 (by 20% in the mini_xml2 case described above), memory usage during
+ compilation (by 14% in that case), and also 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">expression</span> <span class="special">=</span>
+ <span class="identifier">term</span>
+ <span class="special">&gt;&gt;</span> <span class="special">*(</span> <span class="special">(</span><span class="char">'+'</span> <span class="special">&gt;&gt;</span> <span class="identifier">term</span><span class="special">)</span>
+ <span class="special">|</span> <span class="special">(</span><span class="char">'-'</span> <span class="special">&gt;&gt;</span> <span class="identifier">term</span><span class="special">)</span>
+ <span class="special">)</span>
+
+ <span class="special">,</span> <span class="identifier">term</span> <span class="special">=</span>
+ <span class="identifier">factor</span>
+ <span class="special">&gt;&gt;</span> <span class="special">*(</span> <span class="special">(</span><span class="char">'*'</span> <span class="special">&gt;&gt;</span> <span class="identifier">factor</span><span class="special">)</span>
+ <span class="special">|</span> <span class="special">(</span><span class="char">'/'</span> <span class="special">&gt;&gt;</span> <span class="identifier">factor</span><span class="special">)</span>
+ <span class="special">)</span>
+
+ <span class="special">,</span> <span class="identifier">factor</span> <span class="special">=</span>
+ <span class="identifier">uint_</span>
+ <span class="special">|</span> <span class="char">'('</span> <span class="special">&gt;&gt;</span> <span class="identifier">expression</span> <span class="special">&gt;&gt;</span> <span class="char">')'</span>
+ <span class="special">|</span> <span class="special">(</span><span class="char">'-'</span> <span class="special">&gt;&gt;</span> <span class="identifier">factor</span><span class="special">)</span>
+ <span class="special">|</span> <span class="special">(</span><span class="char">'+'</span> <span class="special">&gt;&gt;</span> <span class="identifier">factor</span><span class="special">)</span>
+<span class="special">);</span>
+</pre>
+<p>
+ </p>
+<p>
+ </p>
+<p>
+ The example above can be found here: ../../example/qi/calc1_sr.cpp
+ </p>
+<p>
+ As shown in this code snippet (an extract from the calc1_sr example), subrules
+ can be freely mixed with rules and grammars. Here, a group of 3 subrules
+ (<code class="computeroutput"><span class="identifier">expression</span></code>, <code class="computeroutput"><span class="identifier">term</span></code>, <code class="computeroutput"><span class="identifier">factor</span></code>)
+ is assigned to a rule (named <code class="computeroutput"><span class="identifier">entry</span></code>).
+ This means that parts of a parser can use subrules (typically the innermost,
+ 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="id3092197"></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="id3092300"></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="id3092397"></a>
+ <a class="link" href="subrule.html#spirit_repository.qi_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. skipper (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.qi_components.nonterminal.subrule.synopsis__usage_"></a><h6>
+<a name="id3092560"></a>
+ <a class="link" href="subrule.html#spirit_repository.qi_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">&gt;&gt;</span> <span class="identifier">srB</span> <span class="special">&gt;&gt;</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.qi_components.nonterminal.subrule.parameters__usage_"></a><h6>
+<a name="id3092854"></a>
+ <a class="link" href="subrule.html#spirit_repository.qi_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>
+ Parser 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 parser 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>
+ Parser 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.qi_components.nonterminal.subrule.groups"></a><h6>
+<a name="id3093230"></a>
+ <a class="link" href="subrule.html#spirit_repository.qi_components.nonterminal.subrule.groups">Groups</a>
+ </h6>
+<p>
+ A subrule group (a set of subrule definitions) is a parser, which can be
+ used anywhere in a parser expression (in assignments to rules, as well
+ as directly in arguments to functions such as <code class="computeroutput"><span class="identifier">parse</span></code>).
+ In a group, parsing 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="keyword">char</span> <span class="keyword">const</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">&gt;&gt;</span> <span class="identifier">int_</span> <span class="special">)</span> <span class="comment">// First group in r1.
+</span> <span class="special">&gt;&gt;</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">&gt;&gt;</span> <span class="identifier">int_</span> <span class="special">)</span> <span class="comment">// Only group in r2.
+</span> <span class="special">&gt;&gt;</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="char">'x'</span> <span class="special">&gt;&gt;</span> <span class="identifier">double_</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.qi_components.nonterminal.subrule.attributes"></a><h6>
+<a name="id3093733"></a>
+ <a class="link" href="subrule.html#spirit_repository.qi_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 RHS parser's
+ attribute is automatically propagated to the subrule's synthesized 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.qi_components.nonterminal.subrule.locals"></a><h6>
+<a name="id3093842"></a>
+ <a class="link" href="subrule.html#spirit_repository.qi_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.qi_components.nonterminal.subrule.example"></a><h6>
+<a name="id3093892"></a>
+ <a class="link" href="subrule.html#spirit_repository.qi_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">qi</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">qi_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>
+</pre>
+<p>
+ </p>
+<p>
+ </p>
+<p>
+ Some using declarations:
+ </p>
+<p>
+ </p>
+<p>
+
+</p>
+<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">qi</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">qi</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>
+<span class="keyword">namespace</span> <span class="identifier">ascii</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">ascii</span><span class="special">;</span>
+</pre>
+<p>
+ </p>
+<p>
+ </p>
+<p>
+ A grammar containing only one rule, defined with a group of 5 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">Iterator</span><span class="special">&gt;</span>
+<span class="keyword">struct</span> <span class="identifier">mini_xml_grammar</span>
+ <span class="special">:</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">grammar</span><span class="special">&lt;</span><span class="identifier">Iterator</span><span class="special">,</span> <span class="identifier">mini_xml</span><span class="special">(),</span> <span class="identifier">ascii</span><span class="special">::</span><span class="identifier">space_type</span><span class="special">&gt;</span>
+<span class="special">{</span>
+ <span class="identifier">mini_xml_grammar</span><span class="special">()</span>
+ <span class="special">:</span> <span class="identifier">mini_xml_grammar</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="keyword">using</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">lit</span><span class="special">;</span>
+ <span class="keyword">using</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">lexeme</span><span class="special">;</span>
+ <span class="keyword">using</span> <span class="identifier">ascii</span><span class="special">::</span><span class="identifier">char_</span><span class="special">;</span>
+ <span class="keyword">using</span> <span class="identifier">ascii</span><span class="special">::</span><span class="identifier">string</span><span class="special">;</span>
+ <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">labels</span><span class="special">;</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="identifier">start_tag</span><span class="special">[</span><span class="identifier">_a</span> <span class="special">=</span> <span class="identifier">_1</span><span class="special">]</span>
+ <span class="special">&gt;&gt;</span> <span class="special">*</span><span class="identifier">node</span>
+ <span class="special">&gt;&gt;</span> <span class="identifier">end_tag</span><span class="special">(</span><span class="identifier">_a</span><span class="special">)</span>
+
+ <span class="special">,</span> <span class="identifier">node</span> <span class="special">%=</span> <span class="identifier">xml</span> <span class="special">|</span> <span class="identifier">text</span>
+
+ <span class="special">,</span> <span class="identifier">text</span> <span class="special">%=</span> <span class="identifier">lexeme</span><span class="special">[+(</span><span class="identifier">char_</span> <span class="special">-</span> <span class="char">'&lt;'</span><span class="special">)]</span>
+
+ <span class="special">,</span> <span class="identifier">start_tag</span> <span class="special">%=</span>
+ <span class="char">'&lt;'</span>
+ <span class="special">&gt;&gt;</span> <span class="special">!</span><span class="identifier">lit</span><span class="special">(</span><span class="char">'/'</span><span class="special">)</span>
+ <span class="special">&gt;&gt;</span> <span class="identifier">lexeme</span><span class="special">[+(</span><span class="identifier">char_</span> <span class="special">-</span> <span class="char">'&gt;'</span><span class="special">)]</span>
+ <span class="special">&gt;&gt;</span> <span class="char">'&gt;'</span>
+
+ <span class="special">,</span> <span class="identifier">end_tag</span> <span class="special">%=</span>
+ <span class="string">"&lt;/"</span>
+ <span class="special">&gt;&gt;</span> <span class="identifier">string</span><span class="special">(</span><span class="identifier">_r1</span><span class="special">)</span>
+ <span class="special">&gt;&gt;</span> <span class="char">'&gt;'</span>
+ <span class="special">);</span>
+ <span class="special">}</span>
+
+ <span class="identifier">qi</span><span class="special">::</span><span class="identifier">rule</span><span class="special">&lt;</span><span class="identifier">Iterator</span><span class="special">,</span> <span class="identifier">mini_xml</span><span class="special">(),</span> <span class="identifier">ascii</span><span class="special">::</span><span class="identifier">space_type</span><span class="special">&gt;</span> <span class="identifier">entry</span><span class="special">;</span>
+
+ <span class="identifier">repo</span><span class="special">::</span><span class="identifier">qi</span><span class="special">::</span><span class="identifier">subrule</span><span class="special">&lt;</span><span class="number">0</span><span class="special">,</span> <span class="identifier">mini_xml</span><span class="special">(),</span> <span class="identifier">qi</span><span class="special">::</span><span class="identifier">locals</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;,</span> <span class="identifier">ascii</span><span class="special">::</span><span class="identifier">space_type</span><span class="special">&gt;</span> <span class="identifier">xml</span><span class="special">;</span>
+ <span class="identifier">repo</span><span class="special">::</span><span class="identifier">qi</span><span class="special">::</span><span class="identifier">subrule</span><span class="special">&lt;</span><span class="number">1</span><span class="special">,</span> <span class="identifier">mini_xml_node</span><span class="special">(),</span> <span class="identifier">ascii</span><span class="special">::</span><span class="identifier">space_type</span><span class="special">&gt;</span> <span class="identifier">node</span><span class="special">;</span>
+ <span class="identifier">repo</span><span class="special">::</span><span class="identifier">qi</span><span class="special">::</span><span class="identifier">subrule</span><span class="special">&lt;</span><span class="number">2</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">(),</span> <span class="identifier">ascii</span><span class="special">::</span><span class="identifier">space_type</span><span class="special">&gt;</span> <span class="identifier">text</span><span class="special">;</span>
+ <span class="identifier">repo</span><span class="special">::</span><span class="identifier">qi</span><span class="special">::</span><span class="identifier">subrule</span><span class="special">&lt;</span><span class="number">3</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">(),</span> <span class="identifier">ascii</span><span class="special">::</span><span class="identifier">space_type</span><span class="special">&gt;</span> <span class="identifier">start_tag</span><span class="special">;</span>
+ <span class="identifier">repo</span><span class="special">::</span><span class="identifier">qi</span><span class="special">::</span><span class="identifier">subrule</span><span class="special">&lt;</span><span class="number">4</span><span class="special">,</span> <span class="keyword">void</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">),</span> <span class="identifier">ascii</span><span class="special">::</span><span class="identifier">space_type</span><span class="special">&gt;</span> <span class="identifier">end_tag</span><span class="special">;</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/qi/mini_xml2_sr.cpp
+ </p>
+<a name="spirit_repository.qi_components.nonterminal.subrule.notes"></a><h6>
+<a name="id3095532"></a>
+ <a class="link" href="subrule.html#spirit_repository.qi_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><a accesskey="n" href="../../karma_components.html"><img src="../../../../../../../../doc/html/images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>

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-12 10:07:46 EDT (Wed, 12 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="id1034190"></a>
+<a name="id3034469"></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="id1034298"></a>
+<a name="id3034639"></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/flush_multi_pass.hpp&gt;
+<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="id1034371"></a>
+<a name="id3083546"></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="id1034393"></a>
+<a name="id3083580"></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="id1034417"></a>
+<a name="id3083618"></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="id1034466"></a>
+<a name="id3083690"></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="id1034498"></a>
+<a name="id3083740"></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="id1034714"></a>
+<a name="id3084017"></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-12 10:07:46 EDT (Wed, 12 Aug 2009)
@@ -10,6 +10,7 @@
 
 [/include karma/primitive_generators.qbk]
 [include karma/directives.qbk]
-[/include karma/compount_generators.qbk]
+[/include karma/nonterminals.qbk]
+[/include karma/compound_generators.qbk]
 
 [endsect]

Modified: trunk/libs/spirit/repository/doc/qi.qbk
==============================================================================
--- trunk/libs/spirit/repository/doc/qi.qbk (original)
+++ trunk/libs/spirit/repository/doc/qi.qbk 2009-08-12 10:07:46 EDT (Wed, 12 Aug 2009)
@@ -10,7 +10,8 @@
 
 [include qi/primitive_parsers.qbk]
 [include qi/directives.qbk]
-[/include qi/compount_parsers.qbk]
+[include qi/nonterminals.qbk]
+[/include qi/compound_parsers.qbk]
 
 [endsect] [/ Qi]
 

Added: trunk/libs/spirit/repository/doc/qi/nonterminals.qbk
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/repository/doc/qi/nonterminals.qbk 2009-08-12 10:07:46 EDT (Wed, 12 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 Qi Parser Non-terminals]
+[include subrule.qbk]
+[endsect]

Added: trunk/libs/spirit/repository/doc/qi/subrule.qbk
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/repository/doc/qi/subrule.qbk 2009-08-12 10:07:46 EDT (Wed, 12 Aug 2009)
@@ -0,0 +1,202 @@
+[/==============================================================================
+ 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 Qi subrules]
+
+[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
+static version of the rule.
+
+The strength of subrules is performance. Replacing some rules with subrules
+can make a parser faster (for example the __qi__ calc1 and mini_xml2
+examples, compiled with gcc-4.4, are respectively 6% and 8% faster when using
+subrules instead of rules). 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 1. has a fixed run-time overhead and 2. stops
+inlining.
+
+The weaknesses of subrules are:
+
+* subrules can only be defined and used within the same parser 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 (by 20% in the mini_xml2 case described above), memory usage during
+ compilation (by 14% in that case), and also the risk of hitting compiler
+ limits and/or bugs.
+
+[import ../../example/qi/calc1_sr.cpp]
+
+[subrules_def]
+
+The example above can be found here: [@../../example/qi/calc1_sr.cpp]
+
+As shown in this code snippet (an extract from the calc1_sr example),
+subrules can be freely mixed with rules and grammars. Here, a group of
+3 subrules (`expression`, `term`, `factor`) is assigned to a rule (named
+`entry`). This means that parts of a parser 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/qi/nonterminal/subrule.hpp>
+ #include <boost/spirit/repository/include/qi_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. skipper
+ (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`] [Parser expressions. Can include `sr1` and `sr2`,
+ as well as any other valid parser expressions.]]
+ [[`srA`] [Subrule with a synthesized attribute and inherited
+ attributes.]]
+ [[`srB`] [Subrule with a synthesized attribute.]]
+ [[`srC`] [Subrule with inherited attributes.]]
+ [[`exprA`, `exprB`, `exprC`]
+ [Parser 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 parser, which can be
+used anywhere in a parser expression (in assignments to rules, as well as
+directly in arguments to functions such as `parse`).
+In a group, parsing 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<char const*> r1, r2, r3;
+ subrule<1> sr1;
+ subrule<2> sr2;
+
+ r1 =
+ ( sr1 = 'a' >> int_ ) // 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' >> int_ ) // 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 = 'x' >> double_ ) // 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 RHS parser's attribute is automatically propagated
+ to the subrule's synthesized 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/qi/mini_xml2_sr.cpp]
+
+Some includes:
+
+[mini_xml2_sr_includes]
+
+Some using declarations:
+
+[mini_xml2_sr_using]
+
+A grammar containing only one rule, defined with a group of 5 subrules:
+
+[mini_xml2_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/qi/mini_xml2_sr.cpp]
+
+[heading Notes]
+
+FIXME add compiler-specific bit (MSVC pragmas, g++ option)
+
+[endsect]

Modified: trunk/libs/spirit/repository/example/qi/Jamfile
==============================================================================
--- trunk/libs/spirit/repository/example/qi/Jamfile (original)
+++ trunk/libs/spirit/repository/example/qi/Jamfile 2009-08-12 10:07:46 EDT (Wed, 12 Aug 2009)
@@ -6,9 +6,15 @@
 # file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 #==============================================================================
 
-project spirit_v2_repository/example_qi ;
+project spirit_v2_repository/example_qi
+ : requirements
+ <toolset>gcc:<cxxflags>-ftemplate-depth-300
+ <toolset>darwin:<cxxflags>-ftemplate-depth-300
+ ;
 
 exe qi_confix : confix.cpp ;
 exe qi_distinct : distinct.cpp ;
 exe flush_multi_pass : flush_multi_pass.cpp ;
+exe calc1_sr : calc1_sr.cpp ;
+exe mini_xml2_sr : mini_xml2_sr.cpp ;
 

Added: trunk/libs/spirit/repository/example/qi/calc1_sr.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/repository/example/qi/calc1_sr.cpp 2009-08-12 10:07:46 EDT (Wed, 12 Aug 2009)
@@ -0,0 +1,118 @@
+/*=============================================================================
+ 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)
+=============================================================================*/
+///////////////////////////////////////////////////////////////////////////////
+//
+// Plain calculator example demonstrating the grammar. The parser is a
+// syntax checker only and does not do any semantic evaluation.
+//
+// [ JDG May 10, 2002 ] spirit1
+// [ JDG March 4, 2007 ] spirit2
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include <boost/config/warning_disable.hpp>
+#include <boost/spirit/include/qi.hpp>
+#include <boost/spirit/repository/include/qi_subrule.hpp>
+#include <iostream>
+#include <string>
+
+namespace client
+{
+ namespace qi = boost::spirit::qi;
+ namespace repo = boost::spirit::repository;
+ namespace ascii = boost::spirit::ascii;
+
+ ///////////////////////////////////////////////////////////////////////////////
+ // Our calculator grammar
+ ///////////////////////////////////////////////////////////////////////////////
+ template <typename Iterator>
+ struct calculator : qi::grammar<Iterator, ascii::space_type>
+ {
+ calculator() : calculator::base_type(entry)
+ {
+ using qi::uint_;
+
+ //[subrules_def
+ entry = (
+ expression =
+ term
+ >> *( ('+' >> term)
+ | ('-' >> term)
+ )
+
+ , term =
+ factor
+ >> *( ('*' >> factor)
+ | ('/' >> factor)
+ )
+
+ , factor =
+ uint_
+ | '(' >> expression >> ')'
+ | ('-' >> factor)
+ | ('+' >> factor)
+ );
+ //]
+ }
+
+ qi::rule<Iterator, ascii::space_type> entry;
+
+ repo::qi::subrule<0, ascii::space_type> expression;
+ repo::qi::subrule<1, ascii::space_type> term;
+ repo::qi::subrule<2, ascii::space_type> factor;
+ };
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Main program
+///////////////////////////////////////////////////////////////////////////////
+int
+main()
+{
+ std::cout << "/////////////////////////////////////////////////////////\n\n";
+ std::cout << "Expression parser...\n\n";
+ std::cout << "/////////////////////////////////////////////////////////\n\n";
+ std::cout << "Type an expression...or [q or Q] to quit\n\n";
+
+ using boost::spirit::ascii::space;
+ typedef std::string::const_iterator iterator_type;
+ typedef client::calculator<iterator_type> calculator;
+
+ calculator calc; // Our grammar
+
+ std::string str;
+ while (std::getline(std::cin, str))
+ {
+ if (str.empty() || str[0] == 'q' || str[0] == 'Q')
+ break;
+
+ std::string::const_iterator iter = str.begin();
+ std::string::const_iterator end = str.end();
+ bool r = phrase_parse(iter, end, calc, space);
+
+ if (r && iter == end)
+ {
+ std::cout << "-------------------------\n";
+ std::cout << "Parsing succeeded\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/qi/mini_xml2_sr.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/repository/example/qi/mini_xml2_sr.cpp 2009-08-12 10:07:46 EDT (Wed, 12 Aug 2009)
@@ -0,0 +1,246 @@
+/*=============================================================================
+ 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)
+=============================================================================*/
+///////////////////////////////////////////////////////////////////////////////
+//
+// A mini XML-like parser
+//
+// [ JDG March 25, 2007 ] spirit2
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include <boost/config/warning_disable.hpp>
+//[mini_xml2_sr_includes
+#include <boost/spirit/include/qi.hpp>
+#include <boost/spirit/repository/include/qi_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_stl.hpp>
+#include <boost/fusion/include/adapt_struct.hpp>
+#include <boost/variant/recursive_variant.hpp>
+#include <boost/foreach.hpp>
+
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <vector>
+
+namespace client
+{
+ namespace fusion = boost::fusion;
+ namespace phoenix = boost::phoenix;
+ //[mini_xml2_sr_using
+ namespace qi = boost::spirit::qi;
+ namespace repo = boost::spirit::repository;
+ namespace ascii = boost::spirit::ascii;
+ //]
+
+ ///////////////////////////////////////////////////////////////////////////
+ // 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(
+ client::mini_xml,
+ (std::string, name)
+ (std::vector<client::mini_xml_node>, children)
+)
+
+namespace client
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // Print out the mini xml tree
+ ///////////////////////////////////////////////////////////////////////////
+ int const tabsize = 4;
+
+ void tab(int indent)
+ {
+ for (int i = 0; i < indent; ++i)
+ std::cout << ' ';
+ }
+
+ struct mini_xml_printer
+ {
+ mini_xml_printer(int indent = 0)
+ : indent(indent)
+ {
+ }
+
+ void operator()(mini_xml const& xml) const;
+
+ int indent;
+ };
+
+ struct mini_xml_node_printer : boost::static_visitor<>
+ {
+ mini_xml_node_printer(int indent = 0)
+ : indent(indent)
+ {
+ }
+
+ void operator()(mini_xml const& xml) const
+ {
+ mini_xml_printer(indent+tabsize)(xml);
+ }
+
+ void operator()(std::string const& text) const
+ {
+ tab(indent+tabsize);
+ std::cout << "text: \"" << text << '"' << std::endl;
+ }
+
+ int indent;
+ };
+
+ void mini_xml_printer::operator()(mini_xml const& xml) const
+ {
+ tab(indent);
+ std::cout << "tag: " << xml.name << std::endl;
+ tab(indent);
+ std::cout << '{' << std::endl;
+
+ BOOST_FOREACH(mini_xml_node const& node, xml.children)
+ {
+ boost::apply_visitor(mini_xml_node_printer(indent), node);
+ }
+
+ tab(indent);
+ std::cout << '}' << std::endl;
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Our mini XML grammar definition
+ ///////////////////////////////////////////////////////////////////////////
+ //[mini_xml2_sr_grammar
+ template <typename Iterator>
+ struct mini_xml_grammar
+ : qi::grammar<Iterator, mini_xml(), ascii::space_type>
+ {
+ mini_xml_grammar()
+ : mini_xml_grammar::base_type(entry)
+ {
+ using qi::lit;
+ using qi::lexeme;
+ using ascii::char_;
+ using ascii::string;
+ using namespace qi::labels;
+
+ entry %= (
+ xml %=
+ start_tag[_a = _1]
+ >> *node
+ >> end_tag(_a)
+
+ , node %= xml | text
+
+ , text %= lexeme[+(char_ - '<')]
+
+ , start_tag %=
+ '<'
+ >> !lit('/')
+ >> lexeme[+(char_ - '>')]
+ >> '>'
+
+ , end_tag %=
+ "</"
+ >> string(_r1)
+ >> '>'
+ );
+ }
+
+ qi::rule<Iterator, mini_xml(), ascii::space_type> entry;
+
+ repo::qi::subrule<0, mini_xml(), qi::locals<std::string>, ascii::space_type> xml;
+ repo::qi::subrule<1, mini_xml_node(), ascii::space_type> node;
+ repo::qi::subrule<2, std::string(), ascii::space_type> text;
+ repo::qi::subrule<3, std::string(), ascii::space_type> start_tag;
+ repo::qi::subrule<4, void(std::string), ascii::space_type> end_tag;
+ };
+ //]
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// 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 client::mini_xml_grammar<std::string::const_iterator> mini_xml_grammar;
+ mini_xml_grammar xml; // Our grammar
+ client::mini_xml ast; // Our tree
+
+ using boost::spirit::ascii::space;
+ std::string::const_iterator iter = storage.begin();
+ std::string::const_iterator end = storage.end();
+ bool r = phrase_parse(iter, end, xml, space, ast);
+
+ if (r && iter == end)
+ {
+ std::cout << "-------------------------\n";
+ std::cout << "Parsing succeeded\n";
+ std::cout << "-------------------------\n";
+ client::mini_xml_printer printer;
+ printer(ast);
+ return 0;
+ }
+ else
+ {
+ std::string::const_iterator some = iter+30;
+ std::string context(iter, (some>end)?end: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/test/CMakeLists.txt
==============================================================================
--- trunk/libs/spirit/repository/test/CMakeLists.txt (original)
+++ trunk/libs/spirit/repository/test/CMakeLists.txt 2009-08-12 10:07:46 EDT (Wed, 12 Aug 2009)
@@ -21,6 +21,7 @@
 # run Qi repository tests
 boost_test_run(qi_repo_confix qi/confix.cpp COMPILE_FLAGS ${test_compile_flags})
 boost_test_run(qi_repo_distinct qi/distinct.cpp COMPILE_FLAGS ${test_compile_flags})
+boost_test_run(qi_repo_subrule qi/subrule.cpp COMPILE_FLAGS ${test_compile_flags})
 
 # run Karma repository tests
 boost_test_run(karma_repo_confix karma/confix.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-12 10:07:46 EDT (Wed, 12 Aug 2009)
@@ -24,6 +24,7 @@
     # run Qi repository tests
     [ run qi/confix.cpp : : : : qi_repo_confix ]
     [ run qi/distinct.cpp : : : : qi_repo_distinct ]
+ [ run qi/subrule.cpp : : : : qi_repo_subrule ]
 
     # run Karma repository tests
     [ run karma/confix.cpp : : : : karma_repo_confix ]

Added: trunk/libs/spirit/repository/test/qi/subrule.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/repository/test/qi/subrule.cpp 2009-08-12 10:07:46 EDT (Wed, 12 Aug 2009)
@@ -0,0 +1,395 @@
+/*=============================================================================
+ 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)
+=============================================================================*/
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/spirit/include/qi_operator.hpp>
+#include <boost/spirit/include/qi_char.hpp>
+#include <boost/spirit/include/qi_string.hpp>
+#include <boost/spirit/include/qi_numeric.hpp>
+#include <boost/spirit/include/qi_auxiliary.hpp>
+#include <boost/spirit/include/qi_nonterminal.hpp>
+#include <boost/spirit/include/qi_action.hpp>
+#include <boost/spirit/include/phoenix_core.hpp>
+#include <boost/spirit/include/phoenix_operator.hpp>
+#include <boost/spirit/include/phoenix_object.hpp>
+#include <boost/spirit/include/phoenix_bind.hpp>
+#include <boost/fusion/include/std_pair.hpp>
+
+#include <boost/spirit/repository/include/qi_subrule.hpp>
+
+#include <string>
+#include <cstring>
+#include <iostream>
+#include "test.hpp"
+
+int
+main()
+{
+ using spirit_test::test_attr;
+ using spirit_test::test;
+
+ using namespace boost::spirit::ascii;
+ using namespace boost::spirit::qi::labels;
+ using boost::spirit::qi::locals;
+ using boost::spirit::qi::rule;
+ using boost::spirit::qi::int_;
+ using boost::spirit::qi::fail;
+ using boost::spirit::qi::on_error;
+ using boost::spirit::qi::debug;
+ using boost::spirit::repository::qi::subrule;
+
+ namespace phx = boost::phoenix;
+
+
+ { // basic tests
+
+ subrule<99> entry;
+ subrule<42> a;
+ subrule<48> b;
+ subrule<16> c;
+ rule<char const*> start;
+
+ entry.name("entry");
+ a.name("a");
+ b.name("b");
+ c.name("c");
+ start.name("start");
+
+// debug(entry);
+// debug(a);
+// debug(b);
+// debug(c);
+ debug(start);
+
+ // subrules with no rule
+ BOOST_TEST(test("abcabcacb", (
+ entry = *(a | b | c)
+ , a = 'a'
+ , b = 'b'
+ , c = 'c'
+ )));
+
+ // check subrule group behaves as a parser
+ BOOST_TEST(test("xabcabcacb", 'x' >> (
+ entry = *(a | b | c)
+ , a = 'a'
+ , b = 'b'
+ , c = 'c'
+ )));
+
+ // subrules in a rule
+ start = (
+ entry = *(a | b | c)
+ , a = 'a'
+ , b = 'b'
+ , c = 'c'
+ );
+ BOOST_TEST(test("abcabcacb", start));
+
+ // subrule -> rule call
+ start = (
+ entry = (a | b) >> (start | b)
+ , a = 'a'
+ , b = 'b'
+ );
+ BOOST_TEST(test("aaaabababaaabbb", start));
+ BOOST_TEST(test("aaaabababaaabba", start, false));
+
+ // subrule recursion
+ start = (
+ entry = (a | b) >> (entry | b)
+ , a = 'a'
+ , b = 'b'
+ );
+ BOOST_TEST(test("aaaabababaaabbb", start));
+ BOOST_TEST(test("aaaabababaaabba", start, false));
+
+ // no-ops
+ a = a;
+ subrule<42> aa(a);
+ }
+
+ { // basic tests w/ skipper, subrules declared const
+
+ subrule<0, space_type> const entry("entry");
+ subrule<1, space_type> const a("a");
+ subrule<2, space_type> const b("b");
+ subrule<3, space_type> const c("c");
+ rule<char const*, space_type> start("start");
+
+// debug(entry);
+// debug(a);
+// debug(b);
+// debug(c);
+ debug(start);
+
+ start = (
+ entry = *(a | b | c)
+ , a = 'a'
+ , b = 'b'
+ , c = 'c'
+ );
+ BOOST_TEST(test(" a b c a b c a c b ", start, space));
+
+ start = (
+ entry = (a | b) >> (entry | b)
+ , a = 'a'
+ , b = 'b'
+ );
+ BOOST_TEST(test(" a a a a b a b a b a a a b b b ", start, space));
+ BOOST_TEST(test(" a a a a b a b a b a a a b b a ", start, space, false));
+
+ // no-ops
+ a = a;
+ subrule<1, space_type> aa(a);
+ }
+
+ { // skipper-type tests
+
+ subrule<0> entry_noskip;
+ subrule<0, space_type> entry_skip;
+ subrule<1> a;
+ subrule<2> b;
+ subrule<3> c;
+
+ // check subrules ignore the skipper
+ BOOST_TEST(test(" xabcabcacb", 'x' >> (
+ entry_noskip = *(a | b | c)
+ , a = 'a'
+ , b = 'b'
+ , c = 'c'
+ ), space));
+ BOOST_TEST(!test(" x a b c a b c a c b ", 'x' >> (
+ entry_skip = *(a | b | c)
+ , a = 'a'
+ , b = 'b'
+ , c = 'c'
+ ), space));
+ }
+
+ { // context tests
+
+ char ch;
+ rule<char const*, char()> a;
+ subrule<0, char()> entry;
+
+ a = (entry = alpha[_val = _1])[_val = _1];
+ BOOST_TEST(test("x", a[phx::ref(ch) = _1]));
+ BOOST_TEST(ch == 'x');
+
+ a %= (entry = alpha[_val = _1]);
+ BOOST_TEST(test_attr("z", a, ch)); // attribute is given.
+ BOOST_TEST(ch == 'z');
+ }
+
+ { // auto subrules tests
+
+ char ch;
+ rule<char const*, char()> a;
+ subrule<0, char()> entry;
+
+ a = (entry %= alpha)[_val = _1];
+ BOOST_TEST(test("x", a[phx::ref(ch) = _1]));
+ BOOST_TEST(ch == 'x');
+
+ a %= (entry %= alpha);
+ BOOST_TEST(test_attr("z", a, ch)); // attribute is given.
+ BOOST_TEST(ch == 'z');
+ }
+
+ { // auto subrules tests: allow stl containers as attributes to
+ // sequences (in cases where attributes of the elements
+ // are convertible to the value_type of the container or if
+ // the element itself is an stl container with value_type
+ // that is convertible to the value_type of the attribute).
+
+ std::string s;
+ rule<char const*, std::string()> r;
+ subrule<0, std::string()> entry;
+
+ r %= (entry %= char_ >> *(',' >> char_));
+ BOOST_TEST(test("a,b,c,d,e,f", r[phx::ref(s) = _1]));
+ BOOST_TEST(s == "abcdef");
+
+ BOOST_TEST(test("abcdef", (
+ entry %= char_ >> char_ >> char_ >> char_ >> char_ >> char_
+ )[phx::ref(s) = _1]));
+ BOOST_TEST(s == "abcdef");
+ }
+
+ { // synth attribute value-init
+
+ std::string s;
+ subrule<0, char()> sr;
+ BOOST_TEST(test_attr("abcdef", +(sr = alpha[_val += _1]), s));
+ BOOST_TEST(s == "abcdef");
+ }
+
+ { // auto subrules aliasing tests
+
+ char ch;
+ rule<char const*, char()> r;
+ subrule<0, char()> a;
+ subrule<1, char()> b;
+ r %= (
+ a %= b
+ , b %= alpha
+ );
+
+ BOOST_TEST(test("x", r[phx::ref(ch) = _1]));
+ BOOST_TEST(ch == 'x');
+
+ BOOST_TEST(test_attr("z", r, ch)); // attribute is given.
+ BOOST_TEST(ch == 'z');
+ }
+
+ { // context (w/arg) tests
+
+ char ch;
+
+ // entry subrule with 1 arg
+ rule<char const*, char(int)> a;
+ subrule<1, char(int)> sr1;
+ a %= (
+ sr1 = alpha[_val = _1 + _r1]
+ )(_r1);
+ BOOST_TEST(test("x", a(phx::val(1))[phx::ref(ch) = _1]));
+ BOOST_TEST(ch == 'x' + 1);
+
+ // other subrule with 1 arg
+ subrule<0, char()> sr0;
+ a %= (
+ sr0 %= sr1(1)
+ , sr1 = alpha[_val = _1 + _r1]
+ );
+
+ // allow scalars as subrule args too
+ rule<char const*, char()> b;
+ b %= (
+ sr1 = alpha[_val = _1 + _r1]
+ )(1);
+ BOOST_TEST(test_attr("b", b, ch));
+ BOOST_TEST(ch == 'b' + 1);
+
+ // entry subrule with 2 args
+ subrule<2, char(int, int)> sr2;
+ BOOST_TEST(test_attr("a", (
+ sr2 = alpha[_val = _1 + _r1 + _r2]
+ )(1, 2), ch));
+ BOOST_TEST(ch == 'a' + 1 + 2);
+ }
+
+ { // context (w/ reference arg) tests
+
+ char ch;
+ subrule<0, void(char&)> sr; // 1 arg (reference) - direct
+ BOOST_TEST(test("x", (sr = alpha[_r1 = _1])(phx::ref(ch))));
+ BOOST_TEST(ch == 'x');
+
+ rule<char const*, void(char&)> a; // forwarded via a rule
+ a = (sr = alpha[_r1 = _1])(_r1);
+ BOOST_TEST(test("y", a(phx::ref(ch))));
+ BOOST_TEST(ch == 'y');
+ }
+
+ { // context (w/locals) tests
+
+ rule<char const*> r;
+ subrule<0, locals<char> > a; // 1 local
+ r = (
+ a = alpha[_a = _1] >> char_(_a)
+ );
+ BOOST_TEST(test("aa", r));
+ BOOST_TEST(!test("ax", r));
+ }
+
+ { // context (w/args and locals) tests
+
+ rule<char const*, void(int)> a;
+ subrule<0, void(int), locals<char> > sr; // 1 arg + 1 local
+ a = (
+ sr = alpha[_a = _1 + _r1] >> char_(_a)
+ )(_r1);
+ BOOST_TEST(test("ab", a(phx::val(1))));
+ BOOST_TEST(test("xy", a(phx::val(1))));
+ BOOST_TEST(!test("ax", a(phx::val(1))));
+ }
+
+ { // void() has unused type (void == unused_type)
+
+ std::pair<int, char> attr;
+ subrule<0, void()> sr;
+ BOOST_TEST(test_attr("123ax", int_ >> char_ >> (sr = char_), attr));
+ BOOST_TEST(attr.first == 123);
+ BOOST_TEST(attr.second == 'a');
+ }
+
+ { // test that injected attributes are ok
+
+ rule<char const*> r;
+ subrule<0, char(int)> sr;
+
+ r = (
+ sr = char_(_r1)[_val = _1]
+ )(42);
+ }
+
+ { // show that sra = srb and sra %= srb works as expected
+ subrule<0, int()> sra;
+ subrule<1, int()> srb;
+ int attr;
+
+ BOOST_TEST(test_attr("123", (sra %= int_), attr));
+ BOOST_TEST(attr == 123);
+
+ BOOST_TEST(test_attr("123", (srb %= sra, sra %= int_), attr));
+ BOOST_TEST(attr == 123);
+
+ BOOST_TEST(test_attr("123", (srb = sra, sra %= int_), attr));
+ BOOST_TEST(attr == 123);
+ }
+
+ { // std::string as container attribute with auto subrules
+
+ subrule<0, std::string()> text;
+ std::string attr;
+ BOOST_TEST(test_attr("x", (
+ text %= +(!char_(')') >> !char_('>') >> char_)
+ ), attr));
+ BOOST_TEST(attr == "x");
+ }
+
+// { // error handling
+//
+// using namespace boost::spirit::ascii;
+// using boost::phoenix::construct;
+// using boost::phoenix::bind;
+//
+// rule<char const*> r;
+// r = '(' > int_ > ',' > int_ > ')';
+//
+// on_error<fail>
+// (
+// r, std::cout
+// << phx::val("Error! Expecting: ")
+// << _4
+// << phx::val(", got: \"")
+// << construct<std::string>(_3, _2)
+// << phx::val("\"")
+// << std::endl
+// );
+//
+// BOOST_TEST(test("(123,456)", r));
+// BOOST_TEST(!test("(abc,def)", r));
+// BOOST_TEST(!test("(123,456]", r));
+// BOOST_TEST(!test("(123;456)", r));
+// BOOST_TEST(!test("[123,456]", r));
+// }
+
+ return boost::report_errors();
+}
+


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