summaryrefslogtreecommitdiff
path: root/boost/spirit/repository/home/qi
diff options
context:
space:
mode:
authorAnas Nashif <anas.nashif@intel.com>2012-10-30 12:57:26 -0700
committerAnas Nashif <anas.nashif@intel.com>2012-10-30 12:57:26 -0700
commit1a78a62555be32868418fe52f8e330c9d0f95d5a (patch)
treed3765a80e7d3b9640ec2e930743630cd6b9fce2b /boost/spirit/repository/home/qi
downloadboost-1a78a62555be32868418fe52f8e330c9d0f95d5a.tar.gz
boost-1a78a62555be32868418fe52f8e330c9d0f95d5a.tar.bz2
boost-1a78a62555be32868418fe52f8e330c9d0f95d5a.zip
Imported Upstream version 1.49.0upstream/1.49.0
Diffstat (limited to 'boost/spirit/repository/home/qi')
-rw-r--r--boost/spirit/repository/home/qi/directive.hpp20
-rw-r--r--boost/spirit/repository/home/qi/directive/confix.hpp150
-rw-r--r--boost/spirit/repository/home/qi/directive/distinct.hpp143
-rw-r--r--boost/spirit/repository/home/qi/directive/kwd.hpp588
-rw-r--r--boost/spirit/repository/home/qi/directive/seek.hpp134
-rw-r--r--boost/spirit/repository/home/qi/nonterminal.hpp18
-rw-r--r--boost/spirit/repository/home/qi/nonterminal/subrule.hpp586
-rw-r--r--boost/spirit/repository/home/qi/operator.hpp17
-rw-r--r--boost/spirit/repository/home/qi/operator/detail/keywords.hpp117
-rw-r--r--boost/spirit/repository/home/qi/operator/keywords.hpp640
-rw-r--r--boost/spirit/repository/home/qi/primitive.hpp19
-rw-r--r--boost/spirit/repository/home/qi/primitive/advance.hpp130
-rw-r--r--boost/spirit/repository/home/qi/primitive/flush_multi_pass.hpp92
-rw-r--r--boost/spirit/repository/home/qi/primitive/iter_pos.hpp83
14 files changed, 2737 insertions, 0 deletions
diff --git a/boost/spirit/repository/home/qi/directive.hpp b/boost/spirit/repository/home/qi/directive.hpp
new file mode 100644
index 0000000000..4e21b11400
--- /dev/null
+++ b/boost/spirit/repository/home/qi/directive.hpp
@@ -0,0 +1,20 @@
+// Copyright (c) 2001-2011 Hartmut Kaiser
+// Copyright (c) 2001-2011 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_DIRECTIVE_APR_28_2009_1258PM)
+#define SPIRIT_REPOSITORY_QI_DIRECTIVE_APR_28_2009_1258PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/repository/home/qi/directive/distinct.hpp>
+#include <boost/spirit/repository/home/qi/directive/confix.hpp>
+#include <boost/spirit/repository/home/qi/directive/kwd.hpp>
+#include <boost/spirit/repository/home/qi/directive/seek.hpp>
+
+#endif
+
diff --git a/boost/spirit/repository/home/qi/directive/confix.hpp b/boost/spirit/repository/home/qi/directive/confix.hpp
new file mode 100644
index 0000000000..d51b0011af
--- /dev/null
+++ b/boost/spirit/repository/home/qi/directive/confix.hpp
@@ -0,0 +1,150 @@
+// Copyright (c) 2009 Chris Hoeppler
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_REPOSITORY_QI_CONFIX_JUN_22_2009_1041AM)
+#define BOOST_SPIRIT_REPOSITORY_QI_CONFIX_JUN_22_2009_1041AM
+
+#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/auxiliary/lazy.hpp>
+#include <boost/spirit/home/support/common_terminals.hpp>
+#include <boost/spirit/home/support/info.hpp>
+#include <boost/spirit/home/support/unused.hpp>
+#include <boost/spirit/home/qi/detail/attributes.hpp>
+
+#include <boost/spirit/repository/home/support/confix.hpp>
+
+#include <boost/fusion/include/vector.hpp>
+#include <boost/mpl/or.hpp>
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // Enablers
+ ///////////////////////////////////////////////////////////////////////////
+
+ // enables confix(..., ...)[]
+ template <typename Prefix, typename Suffix>
+ struct use_directive<qi::domain
+ , terminal_ex<repository::tag::confix, fusion::vector2<Prefix, Suffix> > >
+ : mpl::true_ {};
+
+ // enables *lazy* confix(..., ...)[]
+ template <>
+ struct use_lazy_directive<qi::domain, repository::tag::confix, 2>
+ : mpl::true_ {};
+
+}}
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit { namespace repository { namespace qi
+{
+ using repository::confix_type;
+ using repository::confix;
+
+ ///////////////////////////////////////////////////////////////////////////
+ // the confix() generated parser
+ template <typename Subject, typename Prefix, typename Suffix>
+ struct confix_parser
+ : spirit::qi::unary_parser<confix_parser<Subject, Prefix, Suffix> >
+ {
+ typedef Subject subject_type;
+
+ template <typename Context, typename Iterator>
+ struct attribute
+ : traits::attribute_of<subject_type, Context, Iterator>
+ {};
+
+ confix_parser(Subject const& subject, Prefix const& prefix
+ , Suffix const& suffix)
+ : subject(subject), prefix(prefix), suffix(suffix) {}
+
+ template <typename Iterator, typename Context
+ , typename Skipper, typename Attribute>
+ bool parse(Iterator& first, Iterator const& last
+ , Context& context, Skipper const& skipper
+ , Attribute& attr) const
+ {
+ Iterator iter = first;
+
+ if (!(prefix.parse(iter, last, context, skipper, unused) &&
+ subject.parse(iter, last, context, skipper, attr) &&
+ suffix.parse(iter, last, context, skipper, unused)))
+ {
+ return false;
+ }
+
+ first = iter;
+ return true;
+ }
+
+ template <typename Context>
+ info what(Context const& ctx) const
+ {
+ return info("confix", subject.what(ctx));
+ }
+
+ Subject subject;
+ Prefix prefix;
+ Suffix suffix;
+ };
+
+}}}}
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit { namespace qi
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // Parser generators: make_xxx function (objects)
+ ///////////////////////////////////////////////////////////////////////////
+
+ // creates confix(..., ...)[] directive
+ template <typename Prefix, typename Suffix, typename Subject
+ , typename Modifiers>
+ struct make_directive<
+ terminal_ex<repository::tag::confix, fusion::vector2<Prefix, Suffix> >
+ , Subject, Modifiers>
+ {
+ typedef typename
+ result_of::compile<qi::domain, Prefix, Modifiers>::type
+ prefix_type;
+ typedef typename
+ result_of::compile<qi::domain, Suffix, Modifiers>::type
+ suffix_type;
+
+ typedef repository::qi::confix_parser<
+ Subject, prefix_type, suffix_type> result_type;
+
+ template <typename Terminal>
+ result_type operator()(Terminal const& term, Subject const& subject
+ , Modifiers const& modifiers) const
+ {
+ return result_type(subject
+ , compile<qi::domain>(fusion::at_c<0>(term.args), modifiers)
+ , compile<qi::domain>(fusion::at_c<1>(term.args), modifiers));
+ }
+ };
+
+}}}
+
+namespace boost { namespace spirit { namespace traits
+{
+ template <typename Subject, typename Prefix, typename Suffix>
+ struct has_semantic_action<
+ repository::qi::confix_parser<Subject, Prefix, Suffix> >
+ : mpl::or_<
+ has_semantic_action<Subject>
+ , has_semantic_action<Prefix>
+ , has_semantic_action<Suffix>
+ > {};
+}}}
+
+#endif
+
diff --git a/boost/spirit/repository/home/qi/directive/distinct.hpp b/boost/spirit/repository/home/qi/directive/distinct.hpp
new file mode 100644
index 0000000000..740694559e
--- /dev/null
+++ b/boost/spirit/repository/home/qi/directive/distinct.hpp
@@ -0,0 +1,143 @@
+// Copyright (c) 2001-2011 Hartmut Kaiser
+// Copyright (c) 2001-2011 Joel de Guzman
+// Copyright (c) 2003 Vaclav Vesely
+//
+// 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_DISTINCT_MAY_20_2009_0825M)
+#define SPIRIT_REPOSITORY_QI_DISTINCT_MAY_20_2009_0825M
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/qi/skip_over.hpp>
+#include <boost/spirit/home/qi/domain.hpp>
+#include <boost/spirit/home/qi/parser.hpp>
+#include <boost/spirit/home/qi/meta_compiler.hpp>
+#include <boost/spirit/home/qi/detail/unused_skipper.hpp>
+#include <boost/spirit/home/support/common_terminals.hpp>
+#include <boost/spirit/home/support/make_component.hpp>
+#include <boost/spirit/home/support/info.hpp>
+#include <boost/spirit/home/support/unused.hpp>
+#include <boost/spirit/home/qi/detail/attributes.hpp>
+#include <boost/spirit/home/support/string_traits.hpp>
+#include <boost/spirit/home/qi/auxiliary/eps.hpp>
+#include <boost/spirit/home/qi/auxiliary/lazy.hpp>
+#include <boost/spirit/home/qi/directive/lexeme.hpp>
+#include <boost/spirit/home/qi/operator/not_predicate.hpp>
+
+#include <boost/spirit/repository/home/support/distinct.hpp>
+
+#include <boost/fusion/include/at.hpp>
+#include <boost/fusion/include/vector.hpp>
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // Enablers
+ ///////////////////////////////////////////////////////////////////////////
+
+ // enables distinct(...)[...]
+ template <typename Tail>
+ struct use_directive<qi::domain
+ , terminal_ex<repository::tag::distinct, fusion::vector1<Tail> > >
+ : mpl::true_ {};
+
+ // enables *lazy* distinct(...)[...]
+ template <>
+ struct use_lazy_directive<qi::domain, repository::tag::distinct, 1>
+ : mpl::true_ {};
+
+}}
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit { namespace repository {namespace qi
+{
+ using repository::distinct_type;
+ using repository::distinct;
+
+ template <typename Subject, typename Tail, typename Modifier>
+ struct distinct_parser
+ : spirit::qi::unary_parser<distinct_parser<Subject, Tail, Modifier> >
+ {
+ template <typename Context, typename Iterator>
+ struct attribute
+ : traits::attribute_of<Subject, Context, Iterator>
+ {};
+
+ distinct_parser(Subject const& subject, Tail const& tail)
+ : subject(subject), tail(tail) {}
+
+ template <typename Iterator, typename Context
+ , typename Skipper, typename Attribute>
+ bool parse(Iterator& first, Iterator const& last
+ , Context& context, Skipper const& skipper, Attribute& attr) const
+ {
+ Iterator iter = first;
+
+ spirit::qi::skip_over(iter, last, skipper);
+ if (!subject.parse(iter, last, context
+ , spirit::qi::detail::unused_skipper<Skipper>(skipper), attr))
+ return false;
+
+ Iterator i = iter;
+ if (tail.parse(i, last, context, unused, unused))
+ return false;
+
+ first = iter;
+ return true;
+ }
+
+ template <typename Context>
+ info what(Context& /*ctx*/) const
+ {
+ return info("distinct");
+ }
+
+ Subject subject;
+ Tail tail;
+ };
+
+}}}}
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit { namespace qi
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // Parser generators: make_xxx function (objects)
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Tail, typename Subject, typename Modifiers>
+ struct make_directive<
+ terminal_ex<repository::tag::distinct, fusion::vector1<Tail> >
+ , Subject, Modifiers>
+ {
+ typedef typename result_of::compile<qi::domain, Tail, Modifiers>::type
+ tail_type;
+
+ typedef repository::qi::distinct_parser<
+ Subject, tail_type, Modifiers> result_type;
+
+ template <typename Terminal>
+ result_type operator()(Terminal const& term, Subject const& subject
+ , Modifiers const& modifiers) const
+ {
+ return result_type(subject
+ , compile<qi::domain>(fusion::at_c<0>(term.args), modifiers));
+ }
+ };
+
+}}}
+
+namespace boost { namespace spirit { namespace traits
+{
+ template <typename Subject, typename Tail, typename Modifier>
+ struct has_semantic_action<
+ repository::qi::distinct_parser<Subject, Tail, Modifier> >
+ : unary_has_semantic_action<Subject> {};
+}}}
+
+#endif
+
diff --git a/boost/spirit/repository/home/qi/directive/kwd.hpp b/boost/spirit/repository/home/qi/directive/kwd.hpp
new file mode 100644
index 0000000000..79fdc2f6dc
--- /dev/null
+++ b/boost/spirit/repository/home/qi/directive/kwd.hpp
@@ -0,0 +1,588 @@
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+ Copyright (c) 2011 Thomas Bernard
+
+ 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_KWD_NOVEMBER_14_2008_1148AM)
+#define SPIRIT_KWD_NOVEMBER_14_2008_1148AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/qi/meta_compiler.hpp>
+#include <boost/spirit/home/qi/parser.hpp>
+#include <boost/spirit/home/qi/auxiliary/lazy.hpp>
+#include <boost/spirit/home/qi/operator/kleene.hpp>
+#include <boost/spirit/home/support/container.hpp>
+#include <boost/spirit/home/qi/detail/attributes.hpp>
+#include <boost/spirit/home/qi/detail/fail_function.hpp>
+#include <boost/spirit/home/support/info.hpp>
+#include <boost/spirit/repository/home/support/kwd.hpp>
+#include <boost/fusion/include/at.hpp>
+#include <boost/foreach.hpp>
+#include <vector>
+
+namespace boost { namespace spirit
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // Enablers
+ ///////////////////////////////////////////////////////////////////////////
+
+ template < typename T>
+ struct use_directive<qi::domain
+ , terminal_ex<repository::tag::kwd // enables kwd(key)[p]
+ , fusion::vector1<T > >
+ > : traits::is_string<T> {};
+
+ template < typename T>
+ struct use_directive<qi::domain
+ , terminal_ex<repository::tag::ikwd // enables ikwd(key)[p]
+ , fusion::vector1<T > >
+ > : traits::is_string<T> {};
+
+
+ template < typename T1, typename T2>
+ struct use_directive<qi::domain
+ , terminal_ex<repository::tag::kwd // enables kwd(key,exact)[p]
+ , fusion::vector2< T1, T2 > >
+ > : traits::is_string<T1> {};
+
+ template < typename T1, typename T2>
+ struct use_directive<qi::domain
+ , terminal_ex<repository::tag::ikwd // enables ikwd(key,exact)[p]
+ , fusion::vector2< T1, T2 > >
+ > : traits::is_string<T1> {};
+
+ template < typename T1, typename T2>
+ struct use_directive<qi::domain
+ , terminal_ex<repository::tag::kwd // enables kwd(min, max)[p]
+ , fusion::vector3< T1, T2, T2 > >
+ > : traits::is_string<T1> {};
+
+ template < typename T1, typename T2>
+ struct use_directive<qi::domain
+ , terminal_ex<repository::tag::ikwd // enables ikwd(min, max)[p]
+ , fusion::vector3< T1, T2, T2 > >
+ > : traits::is_string<T1> {};
+
+ template < typename T1, typename T2>
+ struct use_directive<qi::domain
+ , terminal_ex<repository::tag::kwd // enables kwd(min, inf)[p]
+ , fusion::vector3<T1, T2, inf_type > >
+ > : traits::is_string<T1> {};
+
+ template < typename T1, typename T2>
+ struct use_directive<qi::domain
+ , terminal_ex<repository::tag::ikwd // enables ikwd(min, inf)[p]
+ , fusion::vector3<T1, T2, inf_type > >
+ > : traits::is_string<T1> {};
+
+
+ /* template <> // enables *lazy* kwd(exact)[p]
+ struct use_lazy_directive<
+ qi::domain
+ , tag::kwd
+ , 1 // arity
+ > : mpl::true_ {};
+
+ template <> // enables *lazy* kwd(min, max)[p]
+ struct use_lazy_directive< // and kwd(min, inf)[p]
+ qi::domain
+ , tag::kwd
+ , 2 // arity
+ > : mpl::true_ {};
+*/
+
+}}
+
+namespace boost { namespace spirit { namespace repository { namespace qi
+{
+ using repository::kwd;
+ using repository::ikwd;
+ using spirit::inf;
+ using spirit::inf_type;
+
+template <typename T>
+ struct kwd_pass_iterator // handles kwd(exact)[p]
+ {
+ kwd_pass_iterator() {}
+ bool flag_init() const { return true; }
+ bool register_successful_parse(bool &flag,T &i) const {
+ flag=true;
+ return true;
+ }
+
+
+ private:
+ // silence MSVC warning C4512: assignment operator could not be generated
+ kwd_pass_iterator& operator= (kwd_pass_iterator const&);
+ };
+
+ template <typename T>
+ struct kwd_exact_iterator // handles kwd(exact)[p]
+ {
+ kwd_exact_iterator(T const exact)
+ : exact(exact){}
+
+ typedef T type;
+ bool flag_init() const { return false; }
+ bool register_successful_parse(bool &flag,T &i) const {
+ i++;
+ if(i<exact)
+ {
+ flag=false;
+ return true;
+ }
+ else if(i==exact)
+ {
+ flag=true;
+ return true;
+ }
+ else
+ return flag=false;
+
+ }
+ T const exact;
+
+ private:
+ // silence MSVC warning C4512: assignment operator could not be generated
+ kwd_exact_iterator& operator= (kwd_exact_iterator const&);
+ };
+
+ template <typename T>
+ struct kwd_finite_iterator // handles kwd(min, max)[p]
+ {
+ kwd_finite_iterator(T const min, T const max)
+ : min BOOST_PREVENT_MACRO_SUBSTITUTION (min)
+ , max BOOST_PREVENT_MACRO_SUBSTITUTION (max)
+ {}
+
+ typedef T type;
+ bool flag_init() const { return min==0; }
+ bool register_successful_parse(bool &flag,T &i) const {
+ i++;
+ if(i<min)
+ {
+ flag=false;
+ return true;
+ }
+ else if(i>=min && i<=max)
+ {
+ return flag=true;
+ }
+ else
+ return flag=false;
+ }
+ T const min;
+ T const max;
+
+ private:
+ // silence MSVC warning C4512: assignment operator could not be generated
+ kwd_finite_iterator& operator= (kwd_finite_iterator const&);
+ };
+
+ template <typename T>
+ struct kwd_infinite_iterator // handles kwd(min, inf)[p]
+ {
+ kwd_infinite_iterator(T const min)
+ : min BOOST_PREVENT_MACRO_SUBSTITUTION (min) {}
+
+ typedef T type;
+ bool flag_init() const { return min==0; }
+ bool register_successful_parse(bool &flag,T &i) const {
+ i++;
+ flag = i>=min;
+ return true;
+ }
+ T const min;
+
+ private:
+ // silence MSVC warning C4512: assignment operator could not be generated
+ kwd_infinite_iterator& operator= (kwd_infinite_iterator const&);
+ };
+
+ // This class enables the transportation of parameters needed to call
+ // the occurence constraint checker from higher level calls
+ // It also serves to select the correct parse function call
+ // of the keyword parser. The implementation changes depending if it is
+ // called form a keyword parsing loop or not.
+ template <typename Skipper, typename NoCasePass>
+ struct skipper_keyword_marker
+ {
+ typedef NoCasePass no_case_pass;
+
+ skipper_keyword_marker(Skipper const &skipper,bool &flag,int &counter) :
+ skipper(skipper)
+ , flag(flag)
+ , counter(counter)
+ {}
+
+ const Skipper &skipper;
+ bool &flag;
+ int &counter;
+ };
+
+ template <typename Subject, typename KeywordType, typename LoopIter , typename NoCase >
+ struct kwd_parser : spirit::qi::unary_parser<kwd_parser<Subject, KeywordType, LoopIter , NoCase > >
+ {
+ struct kwd_parser_id;
+
+ typedef Subject subject_type;
+ typedef NoCase no_case_keyword;
+
+ typedef typename
+ remove_const<typename traits::char_type_of<KeywordType>::type>::type
+ char_type;
+
+ typedef std::basic_string<char_type> keyword_type;
+
+ template <typename Context, typename Iterator>
+ struct attribute
+ {
+ typedef typename
+ traits::build_std_vector<
+ typename traits::attribute_of<
+ Subject, Context, Iterator>::type
+ >::type
+ type;
+ };
+
+
+ kwd_parser(Subject const& subject
+ , typename add_reference<KeywordType>::type keyword
+ , LoopIter const& iter)
+ : subject(subject), iter(iter), keyword(keyword) {}
+
+ // Call the subject parser on a non container attribute
+ template <typename Iterator, typename Context
+ , typename Skipper, typename Attribute>
+ bool parse_impl(Iterator& first, Iterator const& last
+ , Context& context, Skipper const& skipper
+ , Attribute& attr,mpl::false_) const
+ {
+ return subject.parse(first,last,context,skipper,attr);
+ }
+
+ // Call the subject parser on a container attribute
+ template <typename Iterator, typename Context
+ , typename Skipper, typename Attribute>
+ bool parse_impl(Iterator& first, Iterator const& last
+ , Context& context, Skipper const& skipper
+ , Attribute& attr,mpl::true_) const
+ {
+
+ // synthesized attribute needs to be default constructed
+ typename traits::container_value<Attribute>::type val =
+ typename traits::container_value<Attribute>::type();
+
+ Iterator save = first;
+ bool r = subject.parse(first,last,context,skipper, val);
+ if (r)
+ {
+ // push the parsed value into our attribute
+ r = traits::push_back(attr, val);
+ if (!r)
+ first = save;
+ }
+ return r;
+ }
+
+ template <typename Iterator, typename Context
+ , typename Skipper, typename Attribute,typename NoCasePass>
+ bool parse(Iterator& first, Iterator const& last
+ , Context& context, skipper_keyword_marker<Skipper,NoCasePass> const& skipper
+ , Attribute &attr) const
+ {
+
+ typedef typename traits::attribute_of<
+ Subject, Context, Iterator>::type
+ subject_attribute;
+
+ typedef typename mpl::and_<
+ traits::is_container<Attribute>
+ , mpl::not_< traits::is_weak_substitute< subject_attribute,Attribute > >
+ >::type predicate;
+
+ if((no_case_keyword::value && NoCasePass::value) || !NoCasePass::value)
+ {
+ if(parse_impl(first,last,context,skipper.skipper,attr, predicate()))
+ return iter.register_successful_parse(skipper.flag,skipper.counter);
+ }
+ return false;
+ }
+
+ template <typename Iterator, typename Context
+ , typename Skipper, typename Attribute>
+ bool parse(Iterator& first, Iterator const& last
+ , Context& context, Skipper const& skipper
+ , Attribute& attr) const
+ {
+ typedef typename traits::attribute_of<
+ Subject, Context, Iterator>::type
+ subject_attribute;
+
+ typedef typename mpl::and_<
+ traits::is_container<Attribute>
+ , mpl::not_< traits::is_weak_substitute< subject_attribute,Attribute > >
+ >::type predicate;
+
+ // Parse the keyword
+ bool flag = iter.flag_init();
+ int counter = 0;
+ Iterator save = first;
+ spirit::qi::skip_over(first, last, skipper);
+ if(keyword.parse(first,last,context,skipper,unused)){
+ // Followed by the subject parser
+ spirit::qi::skip_over(first, last, skipper);
+ if(parse_impl(first,last,context,skipper,attr, predicate()))
+ {
+ return iter.register_successful_parse(flag,counter);
+ }
+ }
+ first = save;
+ return flag;
+ }
+
+
+ template <typename Context>
+ info what(Context& context) const
+ {
+ if(no_case_keyword::value)
+ return info("ikwd", subject.what(context));
+ else
+ return info("kwd", subject.what(context));
+ }
+
+ Subject subject;
+ LoopIter iter;
+
+ spirit::qi::literal_string<KeywordType, true> keyword;
+ private:
+ // silence MSVC warning C4512: assignment operator could not be generated
+ kwd_parser& operator= (kwd_parser const&);
+
+ template <typename Iterator, typename Context, typename Skipper>
+ static spirit::qi::detail::fail_function<Iterator, Context, Skipper>
+ fail_function(
+ Iterator& first, Iterator const& last
+ , Context& context, Skipper const& skipper)
+ {
+ return spirit::qi::detail::fail_function<Iterator, Context, Skipper>
+ (first, last, context, skipper);
+ }
+
+
+ };
+}}}}
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit { namespace qi
+{
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Parser generators: make_xxx function (objects)
+ ///////////////////////////////////////////////////////////////////////////
+
+ // Directive kwd(key)[p]
+ template <typename T1, typename Subject, typename Modifiers>
+ struct make_directive<
+ terminal_ex<repository::tag::kwd, fusion::vector1<T1> >, Subject, Modifiers>
+ {
+ typedef typename add_const<T1>::type const_keyword;
+ typedef repository::qi::kwd_pass_iterator<int> iterator_type;
+ typedef has_modifier<Modifiers, tag::char_code_base<tag::no_case> > no_case;
+
+
+ typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, no_case > result_type;
+
+ template <typename Terminal>
+ result_type operator()(
+ Terminal const& term, Subject const& subject, unused_type) const
+ {
+ return result_type(subject
+ ,fusion::at_c<0>(term.args)
+ ,iterator_type()
+ );
+ }
+ };
+
+ // Directive ikwd(key)[p]
+ template <typename T1, typename Subject, typename Modifiers>
+ struct make_directive<
+ terminal_ex<repository::tag::ikwd, fusion::vector1<T1> >, Subject, Modifiers>
+ {
+ typedef typename add_const<T1>::type const_keyword;
+ typedef repository::qi::kwd_pass_iterator<int> iterator_type;
+
+ typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_ > result_type;
+
+ template <typename Terminal>
+ result_type operator()(
+ Terminal const& term, Subject const& subject, unused_type) const
+ {
+ /* typename spirit::detail::get_encoding<Modifiers,
+ spirit::char_encoding::standard>::type encoding;*/
+
+ return result_type(subject
+ ,fusion::at_c<0>(term.args)
+ ,iterator_type()
+ );
+ }
+ };
+
+ // Directive kwd(key,exact)[p]
+ template <typename T1, typename T2, typename Subject, typename Modifiers>
+ struct make_directive<
+ terminal_ex<repository::tag::kwd, fusion::vector2<T1,T2> >, Subject, Modifiers>
+ {
+ typedef typename add_const<T1>::type const_keyword;
+ typedef repository::qi::kwd_exact_iterator<T2> iterator_type;
+ typedef has_modifier<Modifiers, tag::char_code_base<tag::no_case> > no_case;
+
+ typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, no_case > result_type;
+
+ template <typename Terminal>
+ result_type operator()(
+ Terminal const& term, Subject const& subject, unused_type) const
+ {
+ return result_type(subject
+ ,fusion::at_c<0>(term.args)
+ ,fusion::at_c<1>(term.args)
+ );
+ }
+ };
+
+ // Directive ikwd(key,exact)[p]
+ template <typename T1, typename T2, typename Subject, typename Modifiers>
+ struct make_directive<
+ terminal_ex<repository::tag::ikwd, fusion::vector2<T1,T2> >, Subject, Modifiers>
+ {
+ typedef typename add_const<T1>::type const_keyword;
+ typedef repository::qi::kwd_exact_iterator<T2> iterator_type;
+
+ typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_ > result_type;
+
+ template <typename Terminal>
+ result_type operator()(
+ Terminal const& term, Subject const& subject, unused_type) const
+ {
+ return result_type(subject
+ , fusion::at_c<0>(term.args)
+ , fusion::at_c<1>(term.args)
+ );
+ }
+ };
+
+ // Directive kwd(min, max)[p]
+ template <typename T1, typename T2, typename Subject, typename Modifiers>
+ struct make_directive<
+ terminal_ex<repository::tag::kwd, fusion::vector3< T1, T2, T2> >, Subject, Modifiers>
+ {
+ typedef typename add_const<T1>::type const_keyword;
+ typedef repository::qi::kwd_finite_iterator<T2> iterator_type;
+ typedef has_modifier<Modifiers, tag::char_code_base<tag::no_case> > no_case;
+
+ typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, no_case > result_type;
+
+ template <typename Terminal>
+ result_type operator()(
+ Terminal const& term, Subject const& subject, unused_type) const
+ {
+ return result_type(subject, fusion::at_c<0>(term.args),
+ iterator_type(
+ fusion::at_c<1>(term.args)
+ , fusion::at_c<2>(term.args)
+ )
+ );
+ }
+ };
+
+ // Directive ikwd(min, max)[p]
+ template <typename T1, typename T2, typename Subject, typename Modifiers>
+ struct make_directive<
+ terminal_ex<repository::tag::ikwd, fusion::vector3< T1, T2, T2> >, Subject, Modifiers>
+ {
+ typedef typename add_const<T1>::type const_keyword;
+ typedef repository::qi::kwd_finite_iterator<T2> iterator_type;
+
+ typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_ > result_type;
+
+ template <typename Terminal>
+ result_type operator()(
+ Terminal const& term, Subject const& subject, unused_type) const
+ {
+
+ return result_type(subject, fusion::at_c<0>(term.args),
+ iterator_type(
+ fusion::at_c<1>(term.args)
+ , fusion::at_c<2>(term.args)
+ )
+ );
+ }
+ };
+
+ // Directive kwd(min, inf)[p]
+ template <typename T1, typename T2, typename Subject, typename Modifiers>
+ struct make_directive<
+ terminal_ex<repository::tag::kwd
+ , fusion::vector3<T1, T2, inf_type> >, Subject, Modifiers>
+ {
+ typedef typename add_const<T1>::type const_keyword;
+ typedef repository::qi::kwd_infinite_iterator<T2> iterator_type;
+ typedef has_modifier<Modifiers, tag::char_code_base<tag::no_case> > no_case;
+
+ typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, no_case > result_type;
+
+ template <typename Terminal>
+ result_type operator()(
+ Terminal const& term, Subject const& subject, unused_type) const
+ {
+ return result_type(subject
+ , fusion::at_c<0>(term.args)
+ , fusion::at_c<1>(term.args)
+ );
+ }
+ };
+
+ // Directive ikwd(min, inf)[p]
+ template <typename T1, typename T2, typename Subject, typename Modifiers>
+ struct make_directive<
+ terminal_ex<repository::tag::ikwd
+ , fusion::vector3<T1, T2, inf_type> >, Subject, Modifiers>
+ {
+ typedef typename add_const<T1>::type const_keyword;
+ typedef repository::qi::kwd_infinite_iterator<T2> iterator_type;
+
+ typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_ > result_type;
+
+ template <typename Terminal>
+ result_type operator()(
+ Terminal const& term, Subject const& subject, unused_type) const
+ {
+ typename spirit::detail::get_encoding<Modifiers,
+ spirit::char_encoding::standard>::type encoding;
+
+ return result_type(subject
+ , fusion::at_c<0>(term.args)
+ , fusion::at_c<1>(term.args)
+ );
+ }
+ };
+
+
+}}}
+
+namespace boost { namespace spirit { namespace traits
+{
+ template <typename Subject, typename KeywordType
+ , typename LoopIter, typename NoCase >
+ struct has_semantic_action<
+ repository::qi::kwd_parser< Subject, KeywordType, LoopIter, NoCase > >
+ : unary_has_semantic_action<Subject> {};
+}}}
+
+#endif
+
diff --git a/boost/spirit/repository/home/qi/directive/seek.hpp b/boost/spirit/repository/home/qi/directive/seek.hpp
new file mode 100644
index 0000000000..951a337cbe
--- /dev/null
+++ b/boost/spirit/repository/home/qi/directive/seek.hpp
@@ -0,0 +1,134 @@
+/*//////////////////////////////////////////////////////////////////////////////
+ Copyright (c) 2011 Jamboree
+
+ 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_QI_SEEK
+#define BOOST_SPIRIT_REPOSITORY_QI_SEEK
+
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+
+#include <boost/spirit/home/qi/meta_compiler.hpp>
+#include <boost/spirit/home/qi/parser.hpp>
+#include <boost/spirit/home/qi/detail/attributes.hpp>
+#include <boost/spirit/home/support/info.hpp>
+#include <boost/spirit/home/support/unused.hpp>
+#include <boost/spirit/home/support/has_semantic_action.hpp>
+#include <boost/spirit/home/support/handles_container.hpp>
+#include <boost/spirit/repository/home/support/seek.hpp>
+
+
+namespace boost { namespace spirit
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // Enablers
+ ///////////////////////////////////////////////////////////////////////////
+
+ // enables seek[...]
+ template <>
+ struct use_directive<qi::domain, repository::tag::seek>
+ : mpl::true_ {};
+}} // namespace boost::spirit
+
+
+namespace boost { namespace spirit { namespace repository {namespace qi
+{
+#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
+ using repository::seek;
+#endif
+ using repository::seek_type;
+
+ template <typename Subject>
+ struct seek_directive
+ : spirit::qi::unary_parser<seek_directive<Subject> >
+ {
+ typedef Subject subject_type;
+
+ template <typename Context, typename Iterator>
+ struct attribute
+ {
+ typedef typename
+ traits::attribute_of<subject_type, Context, Iterator>::type
+ type;
+ };
+
+ seek_directive(Subject const& subject)
+ : subject(subject)
+ {}
+
+ template
+ <
+ typename Iterator, typename Context
+ , typename Skipper, typename Attribute
+ >
+ bool parse
+ (
+ Iterator& first, Iterator const& last
+ , Context& context, Skipper const& skipper
+ , Attribute& attr
+ ) const
+ {
+ for (Iterator it(first); ; ++it)
+ {
+ if (subject.parse(it, last, context, skipper, attr))
+ {
+ first = it;
+ return true;
+ }
+ // fail only after subject fails & no input
+ if (it == last)
+ return false;
+ }
+ }
+
+ template <typename Context>
+ info what(Context& context) const
+ {
+ return info("seek", subject.what(context));
+ }
+
+ Subject subject;
+ };
+}}}} // namespace boost::spirit::repository::qi
+
+
+namespace boost { namespace spirit { namespace qi
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // Parser generators: make_xxx function (objects)
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Subject, typename Modifiers>
+ struct make_directive<repository::tag::seek, Subject, Modifiers>
+ {
+ typedef repository::qi::seek_directive<Subject> result_type;
+
+ result_type operator()(unused_type, Subject const& subject, unused_type) const
+ {
+ return result_type(subject);
+ }
+ };
+}}} // namespace boost::spirit::qi
+
+
+namespace boost { namespace spirit { namespace traits
+{
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Subject>
+ struct has_semantic_action<repository::qi::seek_directive<Subject> >
+ : unary_has_semantic_action<Subject> {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Subject, typename Attribute, typename Context
+ , typename Iterator>
+ struct handles_container<repository::qi::seek_directive<Subject>, Attribute
+ , Context, Iterator>
+ : unary_handles_container<Subject, Attribute, Context, Iterator> {};
+}}} // namespace boost::spirit::traits
+
+
+#endif
diff --git a/boost/spirit/repository/home/qi/nonterminal.hpp b/boost/spirit/repository/home/qi/nonterminal.hpp
new file mode 100644
index 0000000000..6b2dbb8fcb
--- /dev/null
+++ b/boost/spirit/repository/home/qi/nonterminal.hpp
@@ -0,0 +1,18 @@
+// Copyright (c) 2001-2011 Hartmut Kaiser
+// Copyright (c) 2001-2011 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
+
diff --git a/boost/spirit/repository/home/qi/nonterminal/subrule.hpp b/boost/spirit/repository/home/qi/nonterminal/subrule.hpp
new file mode 100644
index 0000000000..a2db38496b
--- /dev/null
+++ b/boost/spirit/repository/home/qi/nonterminal/subrule.hpp
@@ -0,0 +1,586 @@
+/*=============================================================================
+ Copyright (c) 2009 Francois Barel
+ Copyright (c) 2001-2011 Joel de Guzman
+
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#if !defined(BOOST_SPIRIT_REPOSITORY_QI_SUBRULE_AUGUST_06_2009_0239AM)
+#define BOOST_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/parameterized.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/qi/detail/attributes.hpp>
+#include <boost/spirit/home/support/info.hpp>
+#include <boost/spirit/home/support/unused.hpp>
+#include <boost/spirit/home/support/nonterminal/extract_param.hpp>
+#include <boost/spirit/home/support/nonterminal/locals.hpp>
+#include <boost/spirit/repository/home/support/subrule_context.hpp>
+
+#include <boost/fusion/include/as_map.hpp>
+#include <boost/fusion/include/at_key.hpp>
+#include <boost/fusion/include/cons.hpp>
+#include <boost/fusion/include/front.hpp>
+#include <boost/fusion/include/has_key.hpp>
+#include <boost/fusion/include/join.hpp>
+#include <boost/fusion/include/make_map.hpp>
+#include <boost/fusion/include/make_vector.hpp>
+#include <boost/fusion/include/size.hpp>
+#include <boost/fusion/include/vector.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/identity.hpp>
+#include <boost/mpl/int.hpp>
+#include <boost/mpl/vector.hpp>
+#include <boost/type_traits/add_reference.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+
+#if defined(BOOST_MSVC)
+# pragma warning(push)
+# pragma warning(disable: 4355) // 'this' : used in base member initializer list warning
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit { namespace repository { namespace qi
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // 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)
+ {
+ }
+
+ explicit 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::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;
+
+ // do down-stream transformation, provides attribute for
+ // rhs parser
+ typedef traits::transform_attribute<
+ typename make_attribute::type, subrule_attr_type, spirit::qi::domain>
+ transform;
+
+ typename make_attribute::type made_attr = make_attribute::call(attr);
+ typename transform::type attr_ = transform::pre(made_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 (def.binder(first, last, context, skipper))
+ {
+ // do up-stream transformation, this integrates the results
+ // back into the original attribute value, if appropriate
+ traits::post_transform(attr, attr_);
+ return true;
+ }
+
+ // inform attribute transformation of failed rhs
+ traits::fail_transform(attr, attr_);
+ return false;
+ }
+
+ 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::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;
+
+ // do down-stream transformation, provides attribute for
+ // rhs parser
+ typedef traits::transform_attribute<
+ typename make_attribute::type, subrule_attr_type, spirit::qi::domain>
+ transform;
+
+ typename make_attribute::type made_attr = make_attribute::call(attr);
+ typename transform::type attr_ = transform::pre(made_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 (def.binder(first, last, context, skipper))
+ {
+ // do up-stream transformation, this integrates the results
+ // back into the original attribute value, if appropriate
+ traits::post_transform(attr, attr_);
+ return true;
+ }
+
+ // inform attribute transformation of failed rhs
+ traits::fail_transform(attr, attr_);
+ return false;
+ }
+
+ template <typename Context>
+ info what(Context& context) const
+ {
+ // Forward to first subrule.
+ return fusion::front(defs).second.binder.p.what(context);
+ }
+
+ template <typename Defs2>
+ subrule_group<
+ typename fusion::result_of::as_map<
+ typename fusion::result_of::join<
+ Defs const, Defs2 const>::type>::type>
+ operator,(subrule_group<Defs2> const& other) const
+ {
+ typedef subrule_group<
+ typename fusion::result_of::as_map<
+ typename fusion::result_of::join<
+ Defs const, Defs2 const>::type>::type> result_type;
+ return result_type(fusion::as_map(fusion::join(defs, other.defs)));
+ }
+
+ // bring in the operator() overloads
+ this_type const& get_parameterized_subject() const { return *this; }
+ typedef this_type parameterized_subject_type;
+ #include <boost/spirit/home/qi/nonterminal/detail/fcall.hpp>
+
+ Defs defs;
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ // subrule_definition: holds one particular definition of a subrule
+ ///////////////////////////////////////////////////////////////////////////
+ template <
+ int ID_
+ , typename Locals
+ , 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 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
+ >
+ struct subrule
+ : proto::extends<
+ typename proto::terminal<
+ spirit::qi::reference<subrule<ID_, T1, T2> const>
+ >::type
+ , subrule<ID_, T1, T2>
+ >
+ , spirit::qi::parser<subrule<ID_, T1, T2> >
+ {
+ typedef mpl::int_<ID_> id_type;
+ BOOST_STATIC_CONSTANT(int, ID = ID_);
+
+ typedef subrule<ID_, T1, T2> 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> 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;
+
+ 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
+ , 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_;
+ };
+}}}}
+
+#if defined(BOOST_MSVC)
+# pragma warning(pop)
+#endif
+
+#endif
diff --git a/boost/spirit/repository/home/qi/operator.hpp b/boost/spirit/repository/home/qi/operator.hpp
new file mode 100644
index 0000000000..2c3606d007
--- /dev/null
+++ b/boost/spirit/repository/home/qi/operator.hpp
@@ -0,0 +1,17 @@
+// Copyright (c) 2001-2011 Hartmut Kaiser
+// Copyright (c) 2001-2011 Joel de Guzman
+// Copyright (c) 2011 Thomas Bernard
+//
+// 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_OPERATOR_OCT_20_2010_1258PM)
+#define SPIRIT_REPOSITORY_QI_OPERATOR_OCT_20_2010_1258PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/repository/home/qi/operator/keywords.hpp>
+#endif
+
diff --git a/boost/spirit/repository/home/qi/operator/detail/keywords.hpp b/boost/spirit/repository/home/qi/operator/detail/keywords.hpp
new file mode 100644
index 0000000000..81e17715df
--- /dev/null
+++ b/boost/spirit/repository/home/qi/operator/detail/keywords.hpp
@@ -0,0 +1,117 @@
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+ Copyright (c) 2011 Thomas Bernard
+
+ 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_KEYWORDS_DETAIL_MARCH_13_2007_1145PM)
+#define SPIRIT_KEYWORDS_DETAIL_MARCH_13_2007_1145PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+namespace boost { namespace spirit { namespace repository { namespace qi { namespace detail {
+
+ // This helper class enables jumping over intermediate directives
+ // down the kwd parser iteration count checking policy
+ struct register_successful_parse
+ {
+ template <typename Subject>
+ static bool call(Subject const &subject,bool &flag, int &counter)
+ {
+ return subject.iter.register_successful_parse(flag,counter);
+ }
+ template <typename Subject, typename Action>
+ static bool call(spirit::qi::action<Subject, Action> const &subject,bool &flag, int &counter)
+ {
+ return subject.subject.iter.register_successful_parse(flag,counter);
+ }
+ template <typename Subject>
+ static bool call(spirit::qi::hold_directive<Subject> const &subject,bool &flag, int &counter)
+ {
+ return subject.subject.iter.register_successful_parse(flag,counter);
+ }
+ };
+ // Variant visitor class which handles dispatching the parsing to the selected parser
+ // This also handles passing the correct attributes and flags/counters to the subject parsers
+
+ template < typename Elements, typename Iterator ,typename Context ,typename Skipper
+ ,typename Flags ,typename Counters ,typename Attribute, typename NoCasePass>
+ class parse_dispatcher
+ : public boost::static_visitor<bool>
+ {
+ typedef typename add_reference<Attribute>::type attr_reference;
+
+ public:
+ parse_dispatcher(const Elements &elements,Iterator& first, Iterator const& last
+ , Context& context, Skipper const& skipper
+ , Flags &flags, Counters &counters, attr_reference attr) :
+ elements(elements), first(first), last(last)
+ , context(context), skipper(skipper)
+ , flags(flags),counters(counters), attr(attr)
+ {}
+
+ template<typename T> bool operator()(T& idx) const
+ {
+ return call(idx,typename traits::not_is_unused<Attribute>::type());
+ }
+
+ template <typename Subject,typename Index>
+ bool call_subject_unused(
+ Subject const &subject, Iterator &first, Iterator const &last
+ , Context& context, Skipper const& skipper
+ , Index& idx ) const
+ {
+ Iterator save = first;
+ skipper_keyword_marker<Skipper,NoCasePass> marked_skipper(skipper,flags[Index::value],counters[Index::value]);
+
+ if(subject.parse(first,last,context,marked_skipper,unused))
+ {
+ return true;
+ }
+ save = save;
+ return false;
+ }
+
+
+ template <typename Subject,typename Index>
+ bool call_subject(
+ Subject const &subject, Iterator &first, Iterator const &last
+ , Context& context, Skipper const& skipper
+ , Index& idx ) const
+ {
+
+ Iterator save = first;
+ skipper_keyword_marker<Skipper,NoCasePass> marked_skipper(skipper,flags[Index::value],counters[Index::value]);
+ if(subject.parse(first,last,context,marked_skipper,fusion::at_c<Index::value>(attr)))
+ {
+ return true;
+ }
+ save = save;
+ return false;
+ }
+
+ // Handle unused attributes
+ template <typename T> bool call(T &idx, mpl::false_) const{
+ return call_subject_unused(fusion::at_c<T::value>(elements), first, last, context, skipper, idx );
+ }
+ // Handle normal attributes
+ template <typename T> bool call(T &idx, mpl::true_) const{
+ return call_subject(fusion::at_c<T::value>(elements), first, last, context, skipper, idx);
+ }
+
+ const Elements &elements;
+ Iterator &first;
+ const Iterator &last;
+ Context & context;
+ const Skipper &skipper;
+ Flags &flags;
+ Counters &counters;
+ attr_reference attr;
+ };
+
+}}}}}
+
+#endif
diff --git a/boost/spirit/repository/home/qi/operator/keywords.hpp b/boost/spirit/repository/home/qi/operator/keywords.hpp
new file mode 100644
index 0000000000..c32c55c7af
--- /dev/null
+++ b/boost/spirit/repository/home/qi/operator/keywords.hpp
@@ -0,0 +1,640 @@
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+ Copyright (c) 2011 Thomas Bernard
+
+ 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_KEYWORDS_OR_MARCH_13_2007_1145PM)
+#define SPIRIT_KEYWORDS_OR_MARCH_13_2007_1145PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/qi/meta_compiler.hpp>
+#include <boost/spirit/home/qi/domain.hpp>
+#include <boost/spirit/home/qi/detail/permute_function.hpp>
+#include <boost/spirit/home/qi/detail/attributes.hpp>
+#include <boost/spirit/home/support/detail/what_function.hpp>
+#include <boost/spirit/home/support/info.hpp>
+#include <boost/spirit/home/support/unused.hpp>
+#include <boost/fusion/include/iter_fold.hpp>
+#include <boost/fusion/include/at.hpp>
+#include <boost/fusion/include/value_at.hpp>
+#include <boost/optional.hpp>
+#include <boost/foreach.hpp>
+#include <boost/array.hpp>
+#include <boost/spirit/home/qi/string/symbols.hpp>
+#include <boost/spirit/home/qi/string/lit.hpp>
+#include <boost/spirit/home/qi/action/action.hpp>
+#include <boost/spirit/home/qi/directive/hold.hpp>
+#include <boost/mpl/count_if.hpp>
+#include <boost/mpl/range_c.hpp>
+#include <boost/mpl/copy.hpp>
+#include <boost/mpl/size.hpp>
+#include <boost/mpl/equal_to.hpp>
+#include <boost/mpl/back_inserter.hpp>
+#include <boost/variant/static_visitor.hpp>
+#include <boost/type_traits/remove_const.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/spirit/repository/home/qi/operator/detail/keywords.hpp>
+
+
+namespace boost { namespace spirit
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // Enablers
+ ///////////////////////////////////////////////////////////////////////////
+ template <>
+ struct use_operator<qi::domain, proto::tag::divides > // enables /
+ : mpl::true_ {};
+
+ template <>
+ struct flatten_tree<qi::domain, proto::tag::divides> // flattens /
+ : mpl::true_ {};
+}}
+
+namespace boost { namespace spirit { namespace repository { namespace qi
+{
+
+ // kwd directive parser type identification
+ namespace detail
+ {
+ BOOST_MPL_HAS_XXX_TRAIT_DEF(kwd_parser_id)
+
+
+ }
+
+ // kwd directive type query
+ template <typename T>
+ struct is_kwd_parser : detail::has_kwd_parser_id<T> {};
+
+ template <typename Subject, typename Action>
+ struct is_kwd_parser<spirit::qi::action<Subject,Action> > : detail::has_kwd_parser_id<Subject> {};
+
+ template <typename Subject>
+ struct is_kwd_parser<spirit::qi::hold_directive<Subject> > : detail::has_kwd_parser_id<Subject> {};
+
+ // Keywords operator
+ template <typename Elements, typename Modifiers>
+ struct keywords : spirit::qi::nary_parser<keywords<Elements,Modifiers> >
+ {
+ template <typename Context, typename Iterator>
+ struct attribute
+ {
+ // Put all the element attributes in a tuple
+ typedef typename traits::build_attribute_sequence<
+ Elements, Context, traits::sequence_attribute_transform, Iterator, spirit::qi::domain >::type
+ all_attributes;
+
+ // Now, build a fusion vector over the attributes. Note
+ // that build_fusion_vector 1) removes all unused attributes
+ // and 2) may return unused_type if all elements have
+ // unused_type(s).
+ typedef typename
+ traits::build_fusion_vector<all_attributes>::type
+ type;
+ };
+
+ /// Make sure that all subjects are of the kwd type
+ typedef typename mpl::count_if<
+ Elements,
+ mpl::not_<
+ is_kwd_parser<
+ mpl::_1
+ >
+ >
+ > non_kwd_subject_count;
+
+ /// If the assertion fails here then you probably forgot to wrap a
+ /// subject of the / operator in a kwd directive
+ BOOST_MPL_ASSERT_RELATION( non_kwd_subject_count::value, ==, 0 );
+
+ ///////////////////////////////////////////////////////////////////////////
+ // build_parser_tags
+ //
+ // Builds a boost::variant from an mpl::range_c in order to "mark" every
+ // parser of the fusion sequence. The integer constant is used in the parser
+ // dispatcher functor in order to use the parser corresponding to the recognised
+ // keyword.
+ ///////////////////////////////////////////////////////////////////////////
+
+ template <typename Sequence>
+ struct build_parser_tags
+ {
+ // Get the sequence size
+ typedef typename mpl::size< Sequence >::type sequence_size;
+
+ // Create an integer_c constant for every parser in the sequence
+ typedef typename mpl::range_c<int, 0, sequence_size::value>::type int_range;
+
+ // Transform the range_c to an mpl vector in order to be able to transform it into a variant
+ typedef typename mpl::copy<int_range, mpl::back_inserter<mpl::vector<> > >::type int_vector;
+
+ // Build the variant type containing the indexes of the parsers
+ typedef typename
+ spirit::detail::as_variant<
+ int_vector >::type type;
+ };
+
+ // Create a variant type to be able to store parser indexes in the embedded symbols parser
+ typedef typename build_parser_tags< Elements >::type parser_index_type;
+
+ ///////////////////////////////////////////////////////////////////////////
+ // build_char_type_sequence
+ //
+ // Build a fusion sequence from the kwd directive specified character type.
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Sequence >
+ struct build_char_type_sequence
+ {
+ struct element_char_type
+ {
+ template <typename T>
+ struct result;
+
+ template <typename F, typename Element>
+ struct result<F(Element)>
+ {
+ typedef typename Element::char_type type;
+
+ };
+ template <typename F, typename Element,typename Action>
+ struct result<F(spirit::qi::action<Element,Action>) >
+ {
+ typedef typename Element::char_type type;
+ };
+ template <typename F, typename Element>
+ struct result<F(spirit::qi::hold_directive<Element>)>
+ {
+ typedef typename Element::char_type type;
+ };
+
+ // never called, but needed for decltype-based result_of (C++0x)
+ template <typename Element>
+ typename result<element_char_type(Element)>::type
+ operator()(Element&) const;
+ };
+
+ // Compute the list of character types of the child kwd directives
+ typedef typename
+ fusion::result_of::transform<Sequence, element_char_type>::type
+ type;
+ };
+
+
+ ///////////////////////////////////////////////////////////////////////////
+ // get_keyword_char_type
+ //
+ // Collapses the character type comming from the subject kwd parsers and
+ // and checks that they are all identical (necessary in order to be able
+ // to build a tst parser to parse the keywords.
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Sequence>
+ struct get_keyword_char_type
+ {
+ // Make sure each of the types occur only once in the type list
+ typedef typename
+ mpl::fold<
+ Sequence, mpl::vector<>,
+ mpl::if_<
+ mpl::contains<mpl::_1, mpl::_2>,
+ mpl::_1, mpl::push_back<mpl::_1, mpl::_2>
+ >
+ >::type
+ no_duplicate_char_types;
+
+ // If the compiler traps here this means you mixed
+ // character type for the keywords specified in the
+ // kwd directive sequence.
+ BOOST_MPL_ASSERT_RELATION( mpl::size<no_duplicate_char_types>::value, ==, 1 );
+
+ typedef typename mpl::front<no_duplicate_char_types>::type type;
+
+ };
+
+ /// Get the character type for the tst parser
+ typedef typename build_char_type_sequence< Elements >::type char_types;
+ typedef typename get_keyword_char_type< char_types >::type char_type;
+
+ /// Our symbols container
+ typedef spirit::qi::tst< char_type, parser_index_type> keywords_type;
+
+ // Filter functor used for case insensitive parsing
+ template <typename CharEncoding>
+ struct no_case_filter
+ {
+ char_type operator()(char_type ch) const
+ {
+ return static_cast<char_type>(CharEncoding::tolower(ch));
+ }
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ // build_case_type_sequence
+ //
+ // Build a fusion sequence from the kwd/ikwd directives
+ // in order to determine if case sensitive and case insensitive
+ // keywords have been mixed.
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Sequence >
+ struct build_case_type_sequence
+ {
+ struct element_case_type
+ {
+ template <typename T>
+ struct result;
+
+ template <typename F, typename Element>
+ struct result<F(Element)>
+ {
+ typedef typename Element::no_case_keyword type;
+
+ };
+ template <typename F, typename Element,typename Action>
+ struct result<F(spirit::qi::action<Element,Action>) >
+ {
+ typedef typename Element::no_case_keyword type;
+ };
+ template <typename F, typename Element>
+ struct result<F(spirit::qi::hold_directive<Element>)>
+ {
+ typedef typename Element::no_case_keyword type;
+ };
+
+ // never called, but needed for decltype-based result_of (C++0x)
+ template <typename Element>
+ typename result<element_case_type(Element)>::type
+ operator()(Element&) const;
+ };
+
+ // Compute the list of character types of the child kwd directives
+ typedef typename
+ fusion::result_of::transform<Sequence, element_case_type>::type
+ type;
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ // get_nb_case_types
+ //
+ // Counts the number of entries in the case type sequence matching the
+ // CaseType parameter (mpl::true_ -> case insensitve
+ // , mpl::false_ -> case sensitive
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Sequence,typename CaseType>
+ struct get_nb_case_types
+ {
+ // Make sure each of the types occur only once in the type list
+ typedef typename
+ mpl::count_if<
+ Sequence, mpl::equal_to<mpl::_,CaseType>
+ >::type type;
+
+
+ };
+ // Build the case type sequence
+ typedef typename build_case_type_sequence<Elements>::type case_type_sequence;
+ // Count the number of case sensitive entries and case insensitve entries
+ typedef typename get_nb_case_types<case_type_sequence,mpl::true_>::type ikwd_count;
+ typedef typename get_nb_case_types<case_type_sequence,mpl::false_>::type kwd_count;
+ // Get the size of the original sequence
+ typedef typename mpl::size<Elements>::type nb_elements;
+ // Determine if all the kwd directive are case sensitive/insensitive
+ typedef typename mpl::equal_to< ikwd_count, nb_elements>::type all_ikwd;
+ typedef typename mpl::equal_to< kwd_count, nb_elements>::type all_kwd;
+
+ typedef typename mpl::or_< all_kwd, all_ikwd >::type all_directives_of_same_type;
+
+ // Do we have a no case modifier
+ typedef has_modifier<Modifiers, spirit::tag::char_code_base<spirit::tag::no_case> > no_case_modifier;
+
+ // Should the no_case filter always be used ?
+ typedef typename mpl::or_<
+ no_case_modifier,
+ mpl::and_<
+ all_directives_of_same_type
+ ,all_ikwd
+ >
+ >::type
+ no_case;
+
+ typedef no_case_filter<
+ typename spirit::detail::get_encoding_with_case<
+ Modifiers
+ , char_encoding::standard
+ , no_case::value>::type>
+ nc_filter;
+ // Determine the standard case filter type
+ typedef typename mpl::if_<
+ no_case
+ , nc_filter
+ , spirit::qi::tst_pass_through >::type
+ filter_type;
+
+
+ // build a bool array and an integer array which will be used to
+ // check that the repetition constraints of the kwd parsers are
+ // met and bail out a soon as possible
+ typedef boost::array<bool, fusion::result_of::size<Elements>::value> flags_type;
+ typedef boost::array<int, fusion::result_of::size<Elements>::value> counters_type;
+
+
+
+ // Functor which adds all the keywords/subject parser indexes
+ // collected from the subject kwd directives to the keyword tst parser
+ template< typename Sequence >
+ struct keyword_entry_adder
+ {
+ typedef int result_type;
+
+ keyword_entry_adder(shared_ptr<keywords_type> lookup,flags_type &flags) :
+ lookup(lookup)
+ ,flags(flags)
+ {}
+
+ typedef typename fusion::result_of::begin< Sequence >::type sequence_begin;
+
+ template <typename T>
+ int operator()(const int i, const T &parser) const
+ {
+ // Determine the current position being handled
+ typedef typename fusion::result_of::distance< sequence_begin, T >::type position_raw;
+ // Transform the position to a parser index tag
+ typedef typename mpl::integral_c<int,position_raw::value> position;
+
+ return call(i,fusion::deref(parser),position());
+ }
+
+ template <typename T, typename Position, typename Action>
+ int call( const int i, const spirit::qi::action<T,Action> &parser, const Position position ) const
+ {
+
+ // Make the keyword/parse index entry in the tst parser
+ lookup->add(
+ traits::get_begin<char_type>(parser.subject.keyword.str),
+ traits::get_end<char_type>(parser.subject.keyword.str),
+ position
+ );
+ // Get the initial state of the flags array and store it in the flags initializer
+ flags[Position::value]=parser.subject.iter.flag_init();
+ return 0;
+ }
+
+ template <typename T, typename Position>
+ int call( const int i, const T & parser, const Position position) const
+ {
+ // Make the keyword/parse index entry in the tst parser
+ lookup->add(
+ traits::get_begin<char_type>(parser.keyword.str),
+ traits::get_end<char_type>(parser.keyword.str),
+ position
+ );
+ // Get the initial state of the flags array and store it in the flags initializer
+ flags[Position::value]=parser.iter.flag_init();
+ return 0;
+ }
+
+ template <typename T, typename Position>
+ int call( const int i, const spirit::qi::hold_directive<T> & parser, const Position position) const
+ {
+ // Make the keyword/parse index entry in the tst parser
+ lookup->add(
+ traits::get_begin<char_type>(parser.subject.keyword.str),
+ traits::get_end<char_type>(parser.subject.keyword.str),
+ position
+ );
+ // Get the initial state of the flags array and store it in the flags initializer
+ flags[Position::value]=parser.subject.iter.flag_init();
+ return 0;
+ }
+
+
+ shared_ptr<keywords_type> lookup;
+ flags_type & flags;
+ };
+
+
+ keywords(Elements const& elements) :
+ elements(elements)
+ , lookup(new keywords_type())
+ {
+ // Loop through all the subject parsers to build the keyword parser symbol parser
+ keyword_entry_adder<Elements> f1(lookup,flags_init);
+ fusion::iter_fold(this->elements,0,f1);
+ }
+
+ template <typename Iterator, typename Context
+ , typename Skipper, typename Attribute>
+ bool parse(Iterator& first, Iterator const& last
+ , Context& context, Skipper const& skipper
+ , Attribute& attr_) const
+ {
+ // Select which parse function to call
+ // We need to handle the case where kwd / ikwd directives have been mixed
+ // This is where we decide which function should be called.
+ return parse_impl(first, last, context, skipper, attr_,
+ typename mpl::or_<all_directives_of_same_type, no_case>::type()
+ );
+ }
+
+ template <typename Iterator, typename Context
+ , typename Skipper, typename Attribute>
+ bool parse_impl(Iterator& first, Iterator const& last
+ , Context& context, Skipper const& skipper
+ , Attribute& attr_,mpl::true_ /* no ikwd */) const
+ {
+
+ // wrap the attribute in a tuple if it is not a tuple
+ typename traits::wrap_if_not_tuple<Attribute>::type attr(attr_);
+
+ flags_type flags(flags_init);
+ //flags.assign(false);
+
+ counters_type counters;
+ counters.assign(0);
+
+ typedef repository::qi::detail::parse_dispatcher<Elements,Iterator, Context, Skipper
+ , flags_type, counters_type
+ , typename traits::wrap_if_not_tuple<Attribute>::type
+ , mpl::false_ > parser_visitor_type;
+ parser_visitor_type parse_visitor(elements, first, last
+ , context, skipper, flags
+ , counters, attr);
+
+ // We have a bool array 'flags' with one flag for each parser as well as a 'counter'
+ // array.
+ // The kwd directive sets and increments the counter when a successeful parse occured
+ // as well as the slot of the corresponding parser to true in the flags array as soon
+ // the minimum repetition requirement is met and keeps that value to true as long as
+ // the maximum repetition requirement is met.
+ // The parsing takes place here in two steps:
+ // 1) parse a keyword and fetch the parser index associated with that keyword
+ // 2) call the associated parser and store the parsed value in the matching attribute.
+ Iterator save = first;
+ while(true)
+ {
+
+ spirit::qi::skip_over(first, last, skipper);
+ if (parser_index_type* val_ptr
+ = lookup->find(first, last, filter_type()))
+ {
+ spirit::qi::skip_over(first, last, skipper);
+ if(!apply_visitor(parse_visitor,*val_ptr)){
+ first = save;
+ return false;
+ }
+ save = first;
+ }
+ else
+ {
+ // Check that we are leaving the keywords parser in a successfull state
+ BOOST_FOREACH(bool &valid,flags)
+ {
+ if(!valid)
+ {
+ first = save;
+ return false;
+ }
+ }
+ return true;
+ }
+ }
+ return false;
+ }
+
+ // Handle the mixed kwd and ikwd case
+ template <typename Iterator, typename Context
+ , typename Skipper, typename Attribute>
+ bool parse_impl(Iterator& first, Iterator const& last
+ , Context& context, Skipper const& skipper
+ , Attribute& attr_,mpl::false_) const
+ {
+
+ // wrap the attribute in a tuple if it is not a tuple
+ typename traits::wrap_if_not_tuple<Attribute>::type attr(attr_);
+
+ flags_type flags(flags_init);
+ //flags.assign(false);
+
+ counters_type counters;
+ counters.assign(0);
+
+ typedef detail::parse_dispatcher<Elements, Iterator, Context, Skipper
+ , flags_type, counters_type
+ , typename traits::wrap_if_not_tuple<Attribute>::type
+ , mpl::false_> parser_visitor_type;
+
+ typedef detail::parse_dispatcher<Elements, Iterator, Context, Skipper
+ , flags_type, counters_type
+ , typename traits::wrap_if_not_tuple<Attribute>::type
+ , mpl::true_> no_case_parser_visitor_type;
+
+
+ parser_visitor_type parse_visitor(elements,first,last
+ ,context,skipper,flags,counters,attr);
+ no_case_parser_visitor_type no_case_parse_visitor(elements,first,last
+ ,context,skipper,flags,counters,attr);
+
+ // We have a bool array 'flags' with one flag for each parser as well as a 'counter'
+ // array.
+ // The kwd directive sets and increments the counter when a successeful parse occured
+ // as well as the slot of the corresponding parser to true in the flags array as soon
+ // the minimum repetition requirement is met and keeps that value to true as long as
+ // the maximum repetition requirement is met.
+ // The parsing takes place here in two steps:
+ // 1) parse a keyword and fetch the parser index associated with that keyword
+ // 2) call the associated parser and store the parsed value in the matching attribute.
+ Iterator save = first;
+ while(true)
+ {
+ spirit::qi::skip_over(first, last, skipper);
+ // First pass case sensitive
+ Iterator saved_first = first;
+ if (parser_index_type* val_ptr
+ = lookup->find(first, last, spirit::qi::tst_pass_through()))
+ {
+ spirit::qi::skip_over(first, last, skipper);
+ if(!apply_visitor(parse_visitor,*val_ptr)){
+ first = save;
+ return false;
+ }
+ save = first;
+ }
+ // Second pass case insensitive
+ else if(parser_index_type* val_ptr
+ = lookup->find(saved_first,last,nc_filter()))
+ {
+ first = saved_first;
+ spirit::qi::skip_over(first, last, skipper);
+ if(!apply_visitor(no_case_parse_visitor,*val_ptr)){
+ first = save;
+ return false;
+ }
+ save = first;
+ }
+ else
+ {
+ // Check that we are leaving the keywords parser in a successfull state
+ BOOST_FOREACH(bool &valid,flags)
+ {
+ if(!valid)
+ {
+ first = save;
+ return false;
+ }
+ }
+ return true;
+ }
+ }
+ return false;
+ }
+
+ template <typename Context>
+ info what(Context& context) const
+ {
+ info result("keywords");
+ fusion::for_each(elements,
+ spirit::detail::what_function<Context>(result, context));
+ return result;
+ }
+ flags_type flags_init;
+ Elements elements;
+ shared_ptr<keywords_type> lookup;
+
+ };
+}}}}
+
+namespace boost { namespace spirit { namespace qi {
+ ///////////////////////////////////////////////////////////////////////////
+ // Parser generators: make_xxx function (objects)
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Elements, typename Modifiers >
+ struct make_composite<proto::tag::divides, Elements, Modifiers >
+ {
+ typedef repository::qi::keywords<Elements,Modifiers> result_type;
+ result_type operator()(Elements ref, unused_type) const
+ {
+ return result_type(ref);
+ }
+ };
+
+
+}}}
+
+namespace boost { namespace spirit { namespace traits
+{
+ // We specialize this for keywords (see support/attributes.hpp).
+ // For keywords, we only wrap the attribute in a tuple IFF
+ // it is not already a fusion tuple.
+ template <typename Elements, typename Modifiers,typename Attribute>
+ struct pass_attribute<repository::qi::keywords<Elements,Modifiers>, Attribute>
+ : wrap_if_not_tuple<Attribute> {};
+
+ template <typename Elements, typename Modifiers>
+ struct has_semantic_action<repository::qi::keywords<Elements, Modifiers> >
+ : nary_has_semantic_action<Elements> {};
+}}}
+
+#endif
+
diff --git a/boost/spirit/repository/home/qi/primitive.hpp b/boost/spirit/repository/home/qi/primitive.hpp
new file mode 100644
index 0000000000..400e6d9626
--- /dev/null
+++ b/boost/spirit/repository/home/qi/primitive.hpp
@@ -0,0 +1,19 @@
+// Copyright (c) 2001-2011 Hartmut Kaiser
+// Copyright (c) 2001-2011 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_PRIMITIVE_APR_28_2009_1258PM)
+#define SPIRIT_REPOSITORY_QI_PRIMITIVE_APR_28_2009_1258PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/repository/home/qi/primitive/advance.hpp>
+#include <boost/spirit/repository/home/qi/primitive/flush_multi_pass.hpp>
+#include <boost/spirit/repository/home/qi/primitive/iter_pos.hpp>
+
+#endif
+
diff --git a/boost/spirit/repository/home/qi/primitive/advance.hpp b/boost/spirit/repository/home/qi/primitive/advance.hpp
new file mode 100644
index 0000000000..11a74bbb13
--- /dev/null
+++ b/boost/spirit/repository/home/qi/primitive/advance.hpp
@@ -0,0 +1,130 @@
+// Copyright (c) 2011 Aaron Graham
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_REPOSITORY_QI_ADVANCE_JAN_23_2011_1203PM)
+#define BOOST_SPIRIT_REPOSITORY_QI_ADVANCE_JAN_23_2011_1203PM
+
+#include <boost/spirit/include/qi_parse.hpp>
+
+///////////////////////////////////////////////////////////////////////////////
+// definition the place holder
+namespace boost { namespace spirit { namespace repository { namespace qi
+{
+ BOOST_SPIRIT_TERMINAL_EX(advance);
+}}}}
+
+///////////////////////////////////////////////////////////////////////////////
+// implementation the enabler
+namespace boost { namespace spirit
+{
+ template <typename A0>
+ struct use_terminal<qi::domain
+ , terminal_ex<repository::qi::tag::advance, fusion::vector1<A0> > >
+ : mpl::or_<is_integral<A0>, is_enum<A0> >
+ {};
+
+ template <>
+ struct use_lazy_terminal<qi::domain, repository::qi::tag::advance, 1>
+ : mpl::true_
+ {};
+}}
+
+///////////////////////////////////////////////////////////////////////////////
+// implementation of the parser
+namespace boost { namespace spirit { namespace repository { namespace qi
+{
+ template <typename Int>
+ struct advance_parser
+ : boost::spirit::qi::primitive_parser< advance_parser<Int> >
+ {
+ // Define the attribute type exposed by this parser component
+ template <typename Context, typename Iterator>
+ struct attribute
+ {
+ typedef boost::spirit::unused_type type;
+ };
+
+ advance_parser(Int dist)
+ : dist(dist)
+ {}
+
+ // This function is called during the actual parsing process
+ template <typename Iterator, typename Context
+ , typename Skipper, typename Attribute>
+ bool parse(Iterator& first, Iterator const& last
+ , Context&, Skipper&, Attribute&) const
+ {
+ // This series of checks is designed to fail parsing on negative
+ // values, without generating a "expression always evaluates true"
+ // warning on unsigned types.
+ if (dist == Int(0)) return true;
+ if (dist < Int(1)) return false;
+
+ typedef typename std::iterator_traits<Iterator>::iterator_category
+ iterator_category;
+ return advance(first, last, iterator_category());
+ }
+
+ // This function is called during error handling to create
+ // a human readable string for the error context.
+ template <typename Context>
+ boost::spirit::info what(Context&) const
+ {
+ return boost::spirit::info("advance");
+ }
+
+ private:
+ // this is the general implementation used by most iterator categories
+ template <typename Iterator, typename IteratorCategory>
+ bool advance(Iterator& first, Iterator const& last
+ , IteratorCategory) const
+ {
+ Int n = dist;
+ Iterator i = first;
+ while (n)
+ {
+ if (i == last) return false;
+ ++i;
+ --n;
+ }
+ first = i;
+ return true;
+ }
+
+ // this is a specialization for random access iterators
+ template <typename Iterator>
+ bool advance(Iterator& first, Iterator const& last
+ , std::random_access_iterator_tag) const
+ {
+ Iterator const it = first + dist;
+ if (it > last) return false;
+ first = it;
+ return true;
+ }
+
+ Int const dist;
+ };
+}}}}
+
+///////////////////////////////////////////////////////////////////////////////
+// instantiation of the parser
+namespace boost { namespace spirit { namespace qi
+{
+ template <typename Modifiers, typename A0>
+ struct make_primitive<
+ terminal_ex<repository::qi::tag::advance, fusion::vector1<A0> >
+ , Modifiers>
+ {
+ typedef repository::qi::advance_parser<A0> result_type;
+
+ template <typename Terminal>
+ result_type operator()(Terminal const& term, unused_type) const
+ {
+ return result_type(fusion::at_c<0>(term.args));
+ }
+ };
+}}}
+
+#endif
diff --git a/boost/spirit/repository/home/qi/primitive/flush_multi_pass.hpp b/boost/spirit/repository/home/qi/primitive/flush_multi_pass.hpp
new file mode 100644
index 0000000000..cd4ab0c0ca
--- /dev/null
+++ b/boost/spirit/repository/home/qi/primitive/flush_multi_pass.hpp
@@ -0,0 +1,92 @@
+// Copyright (c) 2001-2011 Hartmut Kaiser
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_REPOSITORY_QI_FLUSH_MULTI_PASS_JUL_10_2009_0535PM)
+#define BOOST_SPIRIT_REPOSITORY_QI_FLUSH_MULTI_PASS_JUL_10_2009_0535PM
+
+#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/support/common_terminals.hpp>
+#include <boost/spirit/home/support/info.hpp>
+#include <boost/spirit/home/support/unused.hpp>
+#include <boost/spirit/home/support/attributes.hpp>
+#include <boost/spirit/home/support/multi_pass.hpp>
+
+#include <boost/spirit/repository/home/support/flush_multi_pass.hpp>
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // Enablers
+ ///////////////////////////////////////////////////////////////////////////
+
+ // enables flush_multi_pass
+ template <>
+ struct use_terminal<qi::domain, repository::tag::flush_multi_pass>
+ : mpl::true_ {};
+
+}}
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit { namespace repository { namespace qi
+{
+ using repository::flush_multi_pass_type;
+ using repository::flush_multi_pass;
+
+ ///////////////////////////////////////////////////////////////////////////
+ // for a flush_multi_pass_parser generated parser
+ struct flush_multi_pass_parser
+ : spirit::qi::primitive_parser<flush_multi_pass_parser>
+ {
+ template <typename Context, typename Unused>
+ struct attribute
+ {
+ typedef unused_type 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
+ {
+ spirit::traits::clear_queue(first, traits::clear_mode::clear_always);
+ return true;
+ }
+
+ template <typename Context>
+ info what(Context const& ctx) const
+ {
+ return info("flush_multi_pass");
+ }
+ };
+
+}}}}
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit { namespace qi
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // Parser generators: make_xxx function (objects)
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Modifiers>
+ struct make_primitive<repository::tag::flush_multi_pass, Modifiers>
+ {
+ typedef repository::qi::flush_multi_pass_parser result_type;
+ result_type operator()(unused_type, unused_type) const
+ {
+ return result_type();
+ }
+ };
+
+}}}
+
+#endif
+
diff --git a/boost/spirit/repository/home/qi/primitive/iter_pos.hpp b/boost/spirit/repository/home/qi/primitive/iter_pos.hpp
new file mode 100644
index 0000000000..6925ac2241
--- /dev/null
+++ b/boost/spirit/repository/home/qi/primitive/iter_pos.hpp
@@ -0,0 +1,83 @@
+// Copyright (c) 2001-2011 Hartmut Kaiser
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_REPOSITORY_QI_ITER_POS_NOV_20_2009_1245PM)
+#define BOOST_SPIRIT_REPOSITORY_QI_ITER_POS_NOV_20_2009_1245PM
+
+#include <boost/spirit/include/qi_parse.hpp>
+
+///////////////////////////////////////////////////////////////////////////////
+// definition the place holder
+namespace boost { namespace spirit { namespace repository { namespace qi
+{
+ BOOST_SPIRIT_TERMINAL(iter_pos);
+}}}}
+
+///////////////////////////////////////////////////////////////////////////////
+// implementation the enabler
+namespace boost { namespace spirit
+{
+ // We want custom_parser::iter_pos to be usable as a terminal only,
+ // and only for parser expressions (qi::domain).
+ template <>
+ struct use_terminal<qi::domain, repository::qi::tag::iter_pos>
+ : mpl::true_
+ {};
+}}
+
+///////////////////////////////////////////////////////////////////////////////
+// implementation of the parser
+namespace boost { namespace spirit { namespace repository { namespace qi
+{
+ struct iter_pos_parser
+ : boost::spirit::qi::primitive_parser<iter_pos_parser>
+ {
+ // Define the attribute type exposed by this parser component
+ template <typename Context, typename Iterator>
+ struct attribute
+ {
+ typedef Iterator type;
+ };
+
+ // This function is called during the actual parsing process
+ template <typename Iterator, typename Context
+ , typename Skipper, typename Attribute>
+ bool parse(Iterator& first, Iterator const& last
+ , Context&, Skipper const& skipper, Attribute& attr) const
+ {
+ boost::spirit::qi::skip_over(first, last, skipper);
+ boost::spirit::traits::assign_to(first, attr);
+ return true;
+ }
+
+ // This function is called during error handling to create
+ // a human readable string for the error context.
+ template <typename Context>
+ boost::spirit::info what(Context&) const
+ {
+ return boost::spirit::info("iter_pos");
+ }
+ };
+}}}}
+
+///////////////////////////////////////////////////////////////////////////////
+// instantiation of the parser
+namespace boost { namespace spirit { namespace qi
+{
+ // This is the factory function object invoked in order to create
+ // an instance of our iter_pos_parser.
+ template <typename Modifiers>
+ struct make_primitive<repository::qi::tag::iter_pos, Modifiers>
+ {
+ typedef repository::qi::iter_pos_parser result_type;
+
+ result_type operator()(unused_type, unused_type) const
+ {
+ return result_type();
+ }
+ };
+}}}
+
+#endif