|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r70213 - in trunk/boost/spirit/repository/home/qi: directive operator operator/detail
From: joel_at_[hidden]
Date: 2011-03-19 20:02:13
Author: djowel
Date: 2011-03-19 20:02:11 EDT (Sat, 19 Mar 2011)
New Revision: 70213
URL: http://svn.boost.org/trac/boost/changeset/70213
Log:
patch from teejay
Text files modified:
trunk/boost/spirit/repository/home/qi/directive/kwd.hpp | 70
trunk/boost/spirit/repository/home/qi/operator/detail/keywords.hpp | 2897 -----------
trunk/boost/spirit/repository/home/qi/operator/keywords.hpp | 9624 ---------------------------------------
3 files changed, 98 insertions(+), 12493 deletions(-)
Modified: trunk/boost/spirit/repository/home/qi/directive/kwd.hpp
==============================================================================
--- trunk/boost/spirit/repository/home/qi/directive/kwd.hpp (original)
+++ trunk/boost/spirit/repository/home/qi/directive/kwd.hpp 2011-03-19 20:02:11 EDT (Sat, 19 Mar 2011)
@@ -204,6 +204,26 @@
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 > >
@@ -270,7 +290,31 @@
return r;
}
- template <typename Iterator, typename Context
+ 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
@@ -282,7 +326,7 @@
typedef typename mpl::and_<
traits::is_container<Attribute>
- , mpl::not_< traits::detail::attribute_is_compatible< subject_attribute,Attribute > >
+ , mpl::not_< traits::is_weak_substitute< subject_attribute,Attribute > >
>::type predicate;
// Parse the keyword
@@ -301,27 +345,7 @@
first = save;
return flag;
}
-
- template <typename Iterator, typename Context
- , typename Skipper, typename Attribute>
- bool kwd_loop_parse(Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Attribute& attr, bool no_case_pass) const
- {
-
- typedef typename traits::attribute_of<
- Subject, Context, Iterator>::type
- subject_attribute;
-
- typedef typename mpl::and_<
- traits::is_container<Attribute>
- , mpl::not_< traits::detail::attribute_is_compatible< subject_attribute,Attribute > >
- >::type predicate;
-
- if((no_case_keyword::value && no_case_pass) || !no_case_pass)
- return parse_impl(first,last,context,skipper,attr, predicate());
- return false;
- }
+
template <typename Context>
info what(Context& context) const
Modified: trunk/boost/spirit/repository/home/qi/operator/detail/keywords.hpp
==============================================================================
--- trunk/boost/spirit/repository/home/qi/operator/detail/keywords.hpp (original)
+++ trunk/boost/spirit/repository/home/qi/operator/detail/keywords.hpp 2011-03-19 20:02:11 EDT (Sat, 19 Mar 2011)
@@ -14,2812 +14,26 @@
namespace boost { namespace spirit { namespace repository { namespace qi { namespace detail {
-
- // 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>
- {
- public:
- parse_dispatcher(const Elements &elements,Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Flags &flags, Counters &counters, Attribute& 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;
- if(subject.kwd_loop_parse(first,last,context,skipper,unused, NoCasePass::value ))
- {
- if(subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- return true;
- }
- save = save;
- return false;
- }
-
- template <typename Subject, typename Index, typename Action> bool call_subject_unused(
- spirit::qi::action<Subject, Action> const &subject, Iterator &first
- , Iterator const &last, Context& context, Skipper const& skipper
- , Index &idx) const
- {
-
- typedef typename Subject::template attribute<Context, Iterator>::type attr_type;
- typedef typename traits::make_attribute<attr_type, unused_type> make_attribute;
-
- // create an attribute if one is not supplied
- typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, spirit::qi::domain> transform;
-
- typename make_attribute::type made_attr = make_attribute::call(unused);
- typename transform::type local_attr = transform::pre(made_attr);
-
- Iterator save = first;
- if (subject.subject.kwd_loop_parse(first, last, context, skipper, local_attr, NoCasePass::value ))
- {
- if(subject.subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- {
- // call the function, passing the attribute, the context.
- // The client can return false to fail parsing.
- if (traits::action_dispatch<Subject>()(subject.f, local_attr, context))
- return true;
- }
- }
- // reset iterators if semantic action failed the match
- // retrospectively
- first = 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;
- if(subject.kwd_loop_parse(first,last,context,skipper,fusion::at_c<Index::value>(attr), NoCasePass::value ))
- {
- if(subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- return true;
- }
- save = save;
- return false;
- }
-
- template <typename Subject, typename Index, typename Action> bool call_subject(
- spirit::qi::action<Subject, Action> const &subject, Iterator &first
- , Iterator const &last, Context& context, Skipper const& skipper
- , Index &idx) const
- {
-
- typedef typename Subject::template attribute<Context, Iterator>::type attr_type;
- typedef typename fusion::result_of::value_at<Attribute,typename Index::value>::type subject_attribute;
- typedef typename traits::make_attribute<attr_type, subject_attribute> make_attribute;
-
- // create an attribute if one is not supplied
- typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, spirit::qi::domain> transform;
-
- typename make_attribute::type made_attr = make_attribute::call(fusion::at_c<Index::value>(attr));
- typename transform::type local_attr = transform::pre(made_attr);
-
- Iterator save = first;
- if (subject.subject.kwd_loop_parse(first, last, context, skipper, local_attr, NoCasePass::value ))
- {
- if(subject.subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- {
- // call the function, passing the attribute, the context.
- // The client can return false to fail parsing.
- if (traits::action_dispatch<Subject>()(subject.f, local_attr, context))
- return true;
-
- }
- }
- // reset iterators if semantic action failed the match
- // retrospectively
- first = save;
- return false;
- }
-
- // Handle unused attributes
- template <typename T> bool call(T &idx, mpl::false_) const{
-
- //if( fusion::at_c<T::value>(elements).parse_impl( first, last, context, skipper, unused, mpl::false_() ) )
- 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;
- Attribute &attr;
- };
-
-}}}}}
-
-#endif
-
-/*=============================================================================
- 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 {
-
-
- // 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>
- {
- public:
- parse_dispatcher(const Elements &elements,Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Flags &flags, Counters &counters, Attribute& 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;
- if(subject.kwd_loop_parse(first,last,context,skipper,unused, NoCasePass::value ))
- {
- if(subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- return true;
- }
- save = save;
- return false;
- }
-
- template <typename Subject, typename Index, typename Action> bool call_subject_unused(
- spirit::qi::action<Subject, Action> const &subject, Iterator &first
- , Iterator const &last, Context& context, Skipper const& skipper
- , Index &idx) const
- {
-
- typedef typename Subject::template attribute<Context, Iterator>::type attr_type;
- typedef typename traits::make_attribute<attr_type, unused_type> make_attribute;
-
- // create an attribute if one is not supplied
- typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, spirit::qi::domain> transform;
-
- typename make_attribute::type made_attr = make_attribute::call(unused);
- typename transform::type local_attr = transform::pre(made_attr);
-
- Iterator save = first;
- if (subject.subject.kwd_loop_parse(first, last, context, skipper, local_attr, NoCasePass::value ))
- {
- if(subject.subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- {
- // call the function, passing the attribute, the context.
- // The client can return false to fail parsing.
- if (traits::action_dispatch<Subject>()(subject.f, local_attr, context))
- return true;
- }
- }
- // reset iterators if semantic action failed the match
- // retrospectively
- first = 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;
- if(subject.kwd_loop_parse(first,last,context,skipper,fusion::at_c<Index::value>(attr), NoCasePass::value ))
- {
- if(subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- return true;
- }
- save = save;
- return false;
- }
-
- template <typename Subject, typename Index, typename Action> bool call_subject(
- spirit::qi::action<Subject, Action> const &subject, Iterator &first
- , Iterator const &last, Context& context, Skipper const& skipper
- , Index &idx) const
- {
-
- typedef typename Subject::template attribute<Context, Iterator>::type attr_type;
- typedef typename fusion::result_of::value_at<Attribute,typename Index::value>::type subject_attribute;
- typedef typename traits::make_attribute<attr_type, subject_attribute> make_attribute;
-
- // create an attribute if one is not supplied
- typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, spirit::qi::domain> transform;
-
- typename make_attribute::type made_attr = make_attribute::call(fusion::at_c<Index::value>(attr));
- typename transform::type local_attr = transform::pre(made_attr);
-
- Iterator save = first;
- if (subject.subject.kwd_loop_parse(first, last, context, skipper, local_attr, NoCasePass::value ))
- {
- if(subject.subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- {
- // call the function, passing the attribute, the context.
- // The client can return false to fail parsing.
- if (traits::action_dispatch<Subject>()(subject.f, local_attr, context))
- return true;
-
- }
- }
- // reset iterators if semantic action failed the match
- // retrospectively
- first = save;
- return false;
- }
-
- // Handle unused attributes
- template <typename T> bool call(T &idx, mpl::false_) const{
-
- //if( fusion::at_c<T::value>(elements).parse_impl( first, last, context, skipper, unused, mpl::false_() ) )
- 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;
- Attribute &attr;
- };
-
-}}}}}
-
-#endif
-
-/*=============================================================================
- 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 {
-
-
- // 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>
- {
- public:
- parse_dispatcher(const Elements &elements,Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Flags &flags, Counters &counters, Attribute& 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;
- if(subject.kwd_loop_parse(first,last,context,skipper,unused, NoCasePass::value ))
- {
- if(subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- return true;
- }
- save = save;
- return false;
- }
-
- template <typename Subject, typename Index, typename Action> bool call_subject_unused(
- spirit::qi::action<Subject, Action> const &subject, Iterator &first
- , Iterator const &last, Context& context, Skipper const& skipper
- , Index &idx) const
- {
-
- typedef typename Subject::template attribute<Context, Iterator>::type attr_type;
- typedef typename traits::make_attribute<attr_type, unused_type> make_attribute;
-
- // create an attribute if one is not supplied
- typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, spirit::qi::domain> transform;
-
- typename make_attribute::type made_attr = make_attribute::call(unused);
- typename transform::type local_attr = transform::pre(made_attr);
-
- Iterator save = first;
- if (subject.subject.kwd_loop_parse(first, last, context, skipper, local_attr, NoCasePass::value ))
- {
- if(subject.subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- {
- // call the function, passing the attribute, the context.
- // The client can return false to fail parsing.
- if (traits::action_dispatch<Subject>()(subject.f, local_attr, context))
- return true;
- }
- }
- // reset iterators if semantic action failed the match
- // retrospectively
- first = 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;
- if(subject.kwd_loop_parse(first,last,context,skipper,fusion::at_c<Index::value>(attr), NoCasePass::value ))
- {
- if(subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- return true;
- }
- save = save;
- return false;
- }
-
- template <typename Subject, typename Index, typename Action> bool call_subject(
- spirit::qi::action<Subject, Action> const &subject, Iterator &first
- , Iterator const &last, Context& context, Skipper const& skipper
- , Index &idx) const
- {
-
- typedef typename Subject::template attribute<Context, Iterator>::type attr_type;
- typedef typename fusion::result_of::value_at<Attribute,typename Index::value>::type subject_attribute;
- typedef typename traits::make_attribute<attr_type, subject_attribute> make_attribute;
-
- // create an attribute if one is not supplied
- typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, spirit::qi::domain> transform;
-
- typename make_attribute::type made_attr = make_attribute::call(fusion::at_c<Index::value>(attr));
- typename transform::type local_attr = transform::pre(made_attr);
-
- Iterator save = first;
- if (subject.subject.kwd_loop_parse(first, last, context, skipper, local_attr, NoCasePass::value ))
- {
- if(subject.subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- {
- // call the function, passing the attribute, the context.
- // The client can return false to fail parsing.
- if (traits::action_dispatch<Subject>()(subject.f, local_attr, context))
- return true;
-
- }
- }
- // reset iterators if semantic action failed the match
- // retrospectively
- first = save;
- return false;
- }
-
- // Handle unused attributes
- template <typename T> bool call(T &idx, mpl::false_) const{
-
- //if( fusion::at_c<T::value>(elements).parse_impl( first, last, context, skipper, unused, mpl::false_() ) )
- 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;
- Attribute &attr;
- };
-
-}}}}}
-
-#endif
-
-/*=============================================================================
- 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 {
-
-
- // 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>
- {
- public:
- parse_dispatcher(const Elements &elements,Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Flags &flags, Counters &counters, Attribute& 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;
- if(subject.kwd_loop_parse(first,last,context,skipper,unused, NoCasePass::value ))
- {
- if(subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- return true;
- }
- save = save;
- return false;
- }
-
- template <typename Subject, typename Index, typename Action> bool call_subject_unused(
- spirit::qi::action<Subject, Action> const &subject, Iterator &first
- , Iterator const &last, Context& context, Skipper const& skipper
- , Index &idx) const
- {
-
- typedef typename Subject::template attribute<Context, Iterator>::type attr_type;
- typedef typename traits::make_attribute<attr_type, unused_type> make_attribute;
-
- // create an attribute if one is not supplied
- typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, spirit::qi::domain> transform;
-
- typename make_attribute::type made_attr = make_attribute::call(unused);
- typename transform::type local_attr = transform::pre(made_attr);
-
- Iterator save = first;
- if (subject.subject.kwd_loop_parse(first, last, context, skipper, local_attr, NoCasePass::value ))
- {
- if(subject.subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- {
- // call the function, passing the attribute, the context.
- // The client can return false to fail parsing.
- if (traits::action_dispatch<Subject>()(subject.f, local_attr, context))
- return true;
- }
- }
- // reset iterators if semantic action failed the match
- // retrospectively
- first = 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;
- if(subject.kwd_loop_parse(first,last,context,skipper,fusion::at_c<Index::value>(attr), NoCasePass::value ))
- {
- if(subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- return true;
- }
- save = save;
- return false;
- }
-
- template <typename Subject, typename Index, typename Action> bool call_subject(
- spirit::qi::action<Subject, Action> const &subject, Iterator &first
- , Iterator const &last, Context& context, Skipper const& skipper
- , Index &idx) const
- {
-
- typedef typename Subject::template attribute<Context, Iterator>::type attr_type;
- typedef typename fusion::result_of::value_at<Attribute,typename Index::value>::type subject_attribute;
- typedef typename traits::make_attribute<attr_type, subject_attribute> make_attribute;
-
- // create an attribute if one is not supplied
- typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, spirit::qi::domain> transform;
-
- typename make_attribute::type made_attr = make_attribute::call(fusion::at_c<Index::value>(attr));
- typename transform::type local_attr = transform::pre(made_attr);
-
- Iterator save = first;
- if (subject.subject.kwd_loop_parse(first, last, context, skipper, local_attr, NoCasePass::value ))
- {
- if(subject.subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- {
- // call the function, passing the attribute, the context.
- // The client can return false to fail parsing.
- if (traits::action_dispatch<Subject>()(subject.f, local_attr, context))
- return true;
-
- }
- }
- // reset iterators if semantic action failed the match
- // retrospectively
- first = save;
- return false;
- }
-
- // Handle unused attributes
- template <typename T> bool call(T &idx, mpl::false_) const{
-
- //if( fusion::at_c<T::value>(elements).parse_impl( first, last, context, skipper, unused, mpl::false_() ) )
- 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;
- Attribute &attr;
- };
-
-}}}}}
-
-#endif
-
-/*=============================================================================
- 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 {
-
-
- // 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>
- {
- public:
- parse_dispatcher(const Elements &elements,Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Flags &flags, Counters &counters, Attribute& 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;
- if(subject.kwd_loop_parse(first,last,context,skipper,unused, NoCasePass::value ))
- {
- if(subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- return true;
- }
- save = save;
- return false;
- }
-
- template <typename Subject, typename Index, typename Action> bool call_subject_unused(
- spirit::qi::action<Subject, Action> const &subject, Iterator &first
- , Iterator const &last, Context& context, Skipper const& skipper
- , Index &idx) const
- {
-
- typedef typename Subject::template attribute<Context, Iterator>::type attr_type;
- typedef typename traits::make_attribute<attr_type, unused_type> make_attribute;
-
- // create an attribute if one is not supplied
- typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, spirit::qi::domain> transform;
-
- typename make_attribute::type made_attr = make_attribute::call(unused);
- typename transform::type local_attr = transform::pre(made_attr);
-
- Iterator save = first;
- if (subject.subject.kwd_loop_parse(first, last, context, skipper, local_attr, NoCasePass::value ))
- {
- if(subject.subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- {
- // call the function, passing the attribute, the context.
- // The client can return false to fail parsing.
- if (traits::action_dispatch<Subject>()(subject.f, local_attr, context))
- return true;
- }
- }
- // reset iterators if semantic action failed the match
- // retrospectively
- first = 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;
- if(subject.kwd_loop_parse(first,last,context,skipper,fusion::at_c<Index::value>(attr), NoCasePass::value ))
- {
- if(subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- return true;
- }
- save = save;
- return false;
- }
-
- template <typename Subject, typename Index, typename Action> bool call_subject(
- spirit::qi::action<Subject, Action> const &subject, Iterator &first
- , Iterator const &last, Context& context, Skipper const& skipper
- , Index &idx) const
- {
-
- typedef typename Subject::template attribute<Context, Iterator>::type attr_type;
- typedef typename fusion::result_of::value_at<Attribute,typename Index::value>::type subject_attribute;
- typedef typename traits::make_attribute<attr_type, subject_attribute> make_attribute;
-
- // create an attribute if one is not supplied
- typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, spirit::qi::domain> transform;
-
- typename make_attribute::type made_attr = make_attribute::call(fusion::at_c<Index::value>(attr));
- typename transform::type local_attr = transform::pre(made_attr);
-
- Iterator save = first;
- if (subject.subject.kwd_loop_parse(first, last, context, skipper, local_attr, NoCasePass::value ))
- {
- if(subject.subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- {
- // call the function, passing the attribute, the context.
- // The client can return false to fail parsing.
- if (traits::action_dispatch<Subject>()(subject.f, local_attr, context))
- return true;
-
- }
- }
- // reset iterators if semantic action failed the match
- // retrospectively
- first = save;
- return false;
- }
-
- // Handle unused attributes
- template <typename T> bool call(T &idx, mpl::false_) const{
-
- //if( fusion::at_c<T::value>(elements).parse_impl( first, last, context, skipper, unused, mpl::false_() ) )
- 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;
- Attribute &attr;
- };
-
-}}}}}
-
-#endif
-
-/*=============================================================================
- 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 {
-
-
- // 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>
- {
- public:
- parse_dispatcher(const Elements &elements,Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Flags &flags, Counters &counters, Attribute& 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;
- if(subject.kwd_loop_parse(first,last,context,skipper,unused, NoCasePass::value ))
- {
- if(subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- return true;
- }
- save = save;
- return false;
- }
-
- template <typename Subject, typename Index, typename Action> bool call_subject_unused(
- spirit::qi::action<Subject, Action> const &subject, Iterator &first
- , Iterator const &last, Context& context, Skipper const& skipper
- , Index &idx) const
- {
-
- typedef typename Subject::template attribute<Context, Iterator>::type attr_type;
- typedef typename traits::make_attribute<attr_type, unused_type> make_attribute;
-
- // create an attribute if one is not supplied
- typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, spirit::qi::domain> transform;
-
- typename make_attribute::type made_attr = make_attribute::call(unused);
- typename transform::type local_attr = transform::pre(made_attr);
-
- Iterator save = first;
- if (subject.subject.kwd_loop_parse(first, last, context, skipper, local_attr, NoCasePass::value ))
- {
- if(subject.subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- {
- // call the function, passing the attribute, the context.
- // The client can return false to fail parsing.
- if (traits::action_dispatch<Subject>()(subject.f, local_attr, context))
- return true;
- }
- }
- // reset iterators if semantic action failed the match
- // retrospectively
- first = 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;
- if(subject.kwd_loop_parse(first,last,context,skipper,fusion::at_c<Index::value>(attr), NoCasePass::value ))
- {
- if(subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- return true;
- }
- save = save;
- return false;
- }
-
- template <typename Subject, typename Index, typename Action> bool call_subject(
- spirit::qi::action<Subject, Action> const &subject, Iterator &first
- , Iterator const &last, Context& context, Skipper const& skipper
- , Index &idx) const
- {
-
- typedef typename Subject::template attribute<Context, Iterator>::type attr_type;
- typedef typename fusion::result_of::value_at<Attribute,typename Index::value>::type subject_attribute;
- typedef typename traits::make_attribute<attr_type, subject_attribute> make_attribute;
-
- // create an attribute if one is not supplied
- typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, spirit::qi::domain> transform;
-
- typename make_attribute::type made_attr = make_attribute::call(fusion::at_c<Index::value>(attr));
- typename transform::type local_attr = transform::pre(made_attr);
-
- Iterator save = first;
- if (subject.subject.kwd_loop_parse(first, last, context, skipper, local_attr, NoCasePass::value ))
- {
- if(subject.subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- {
- // call the function, passing the attribute, the context.
- // The client can return false to fail parsing.
- if (traits::action_dispatch<Subject>()(subject.f, local_attr, context))
- return true;
-
- }
- }
- // reset iterators if semantic action failed the match
- // retrospectively
- first = save;
- return false;
- }
-
- // Handle unused attributes
- template <typename T> bool call(T &idx, mpl::false_) const{
-
- //if( fusion::at_c<T::value>(elements).parse_impl( first, last, context, skipper, unused, mpl::false_() ) )
- 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;
- Attribute &attr;
- };
-
-}}}}}
-
-#endif
-
-/*=============================================================================
- 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 {
-
-
- // 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>
- {
- public:
- parse_dispatcher(const Elements &elements,Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Flags &flags, Counters &counters, Attribute& 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;
- if(subject.kwd_loop_parse(first,last,context,skipper,unused, NoCasePass::value ))
- {
- if(subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- return true;
- }
- save = save;
- return false;
- }
-
- template <typename Subject, typename Index, typename Action> bool call_subject_unused(
- spirit::qi::action<Subject, Action> const &subject, Iterator &first
- , Iterator const &last, Context& context, Skipper const& skipper
- , Index &idx) const
- {
-
- typedef typename Subject::template attribute<Context, Iterator>::type attr_type;
- typedef typename traits::make_attribute<attr_type, unused_type> make_attribute;
-
- // create an attribute if one is not supplied
- typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, spirit::qi::domain> transform;
-
- typename make_attribute::type made_attr = make_attribute::call(unused);
- typename transform::type local_attr = transform::pre(made_attr);
-
- Iterator save = first;
- if (subject.subject.kwd_loop_parse(first, last, context, skipper, local_attr, NoCasePass::value ))
- {
- if(subject.subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- {
- // call the function, passing the attribute, the context.
- // The client can return false to fail parsing.
- if (traits::action_dispatch<Subject>()(subject.f, local_attr, context))
- return true;
- }
- }
- // reset iterators if semantic action failed the match
- // retrospectively
- first = 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;
- if(subject.kwd_loop_parse(first,last,context,skipper,fusion::at_c<Index::value>(attr), NoCasePass::value ))
- {
- if(subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- return true;
- }
- save = save;
- return false;
- }
-
- template <typename Subject, typename Index, typename Action> bool call_subject(
- spirit::qi::action<Subject, Action> const &subject, Iterator &first
- , Iterator const &last, Context& context, Skipper const& skipper
- , Index &idx) const
- {
-
- typedef typename Subject::template attribute<Context, Iterator>::type attr_type;
- typedef typename fusion::result_of::value_at<Attribute,typename Index::value>::type subject_attribute;
- typedef typename traits::make_attribute<attr_type, subject_attribute> make_attribute;
-
- // create an attribute if one is not supplied
- typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, spirit::qi::domain> transform;
-
- typename make_attribute::type made_attr = make_attribute::call(fusion::at_c<Index::value>(attr));
- typename transform::type local_attr = transform::pre(made_attr);
-
- Iterator save = first;
- if (subject.subject.kwd_loop_parse(first, last, context, skipper, local_attr, NoCasePass::value ))
- {
- if(subject.subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- {
- // call the function, passing the attribute, the context.
- // The client can return false to fail parsing.
- if (traits::action_dispatch<Subject>()(subject.f, local_attr, context))
- return true;
-
- }
- }
- // reset iterators if semantic action failed the match
- // retrospectively
- first = save;
- return false;
- }
-
- // Handle unused attributes
- template <typename T> bool call(T &idx, mpl::false_) const{
-
- //if( fusion::at_c<T::value>(elements).parse_impl( first, last, context, skipper, unused, mpl::false_() ) )
- 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;
- Attribute &attr;
- };
-
-}}}}}
-
-#endif
-
-/*=============================================================================
- 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 {
-
-
- // 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>
- {
- public:
- parse_dispatcher(const Elements &elements,Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Flags &flags, Counters &counters, Attribute& 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;
- if(subject.kwd_loop_parse(first,last,context,skipper,unused, NoCasePass::value ))
- {
- if(subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- return true;
- }
- save = save;
- return false;
- }
-
- template <typename Subject, typename Index, typename Action> bool call_subject_unused(
- spirit::qi::action<Subject, Action> const &subject, Iterator &first
- , Iterator const &last, Context& context, Skipper const& skipper
- , Index &idx) const
- {
-
- typedef typename Subject::template attribute<Context, Iterator>::type attr_type;
- typedef typename traits::make_attribute<attr_type, unused_type> make_attribute;
-
- // create an attribute if one is not supplied
- typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, spirit::qi::domain> transform;
-
- typename make_attribute::type made_attr = make_attribute::call(unused);
- typename transform::type local_attr = transform::pre(made_attr);
-
- Iterator save = first;
- if (subject.subject.kwd_loop_parse(first, last, context, skipper, local_attr, NoCasePass::value ))
- {
- if(subject.subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- {
- // call the function, passing the attribute, the context.
- // The client can return false to fail parsing.
- if (traits::action_dispatch<Subject>()(subject.f, local_attr, context))
- return true;
- }
- }
- // reset iterators if semantic action failed the match
- // retrospectively
- first = 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;
- if(subject.kwd_loop_parse(first,last,context,skipper,fusion::at_c<Index::value>(attr), NoCasePass::value ))
- {
- if(subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- return true;
- }
- save = save;
- return false;
- }
-
- template <typename Subject, typename Index, typename Action> bool call_subject(
- spirit::qi::action<Subject, Action> const &subject, Iterator &first
- , Iterator const &last, Context& context, Skipper const& skipper
- , Index &idx) const
- {
-
- typedef typename Subject::template attribute<Context, Iterator>::type attr_type;
- typedef typename fusion::result_of::value_at<Attribute,typename Index::value>::type subject_attribute;
- typedef typename traits::make_attribute<attr_type, subject_attribute> make_attribute;
-
- // create an attribute if one is not supplied
- typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, spirit::qi::domain> transform;
-
- typename make_attribute::type made_attr = make_attribute::call(fusion::at_c<Index::value>(attr));
- typename transform::type local_attr = transform::pre(made_attr);
-
- Iterator save = first;
- if (subject.subject.kwd_loop_parse(first, last, context, skipper, local_attr, NoCasePass::value ))
- {
- if(subject.subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- {
- // call the function, passing the attribute, the context.
- // The client can return false to fail parsing.
- if (traits::action_dispatch<Subject>()(subject.f, local_attr, context))
- return true;
-
- }
- }
- // reset iterators if semantic action failed the match
- // retrospectively
- first = save;
- return false;
- }
-
- // Handle unused attributes
- template <typename T> bool call(T &idx, mpl::false_) const{
-
- //if( fusion::at_c<T::value>(elements).parse_impl( first, last, context, skipper, unused, mpl::false_() ) )
- 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;
- Attribute &attr;
- };
-
-}}}}}
-
-#endif
-
-/*=============================================================================
- 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 {
-
-
- // 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>
- {
- public:
- parse_dispatcher(const Elements &elements,Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Flags &flags, Counters &counters, Attribute& 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;
- if(subject.kwd_loop_parse(first,last,context,skipper,unused, NoCasePass::value ))
- {
- if(subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- return true;
- }
- save = save;
- return false;
- }
-
- template <typename Subject, typename Index, typename Action> bool call_subject_unused(
- spirit::qi::action<Subject, Action> const &subject, Iterator &first
- , Iterator const &last, Context& context, Skipper const& skipper
- , Index &idx) const
- {
-
- typedef typename Subject::template attribute<Context, Iterator>::type attr_type;
- typedef typename traits::make_attribute<attr_type, unused_type> make_attribute;
-
- // create an attribute if one is not supplied
- typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, spirit::qi::domain> transform;
-
- typename make_attribute::type made_attr = make_attribute::call(unused);
- typename transform::type local_attr = transform::pre(made_attr);
-
- Iterator save = first;
- if (subject.subject.kwd_loop_parse(first, last, context, skipper, local_attr, NoCasePass::value ))
- {
- if(subject.subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- {
- // call the function, passing the attribute, the context.
- // The client can return false to fail parsing.
- if (traits::action_dispatch<Subject>()(subject.f, local_attr, context))
- return true;
- }
- }
- // reset iterators if semantic action failed the match
- // retrospectively
- first = 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;
- if(subject.kwd_loop_parse(first,last,context,skipper,fusion::at_c<Index::value>(attr), NoCasePass::value ))
- {
- if(subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- return true;
- }
- save = save;
- return false;
- }
-
- template <typename Subject, typename Index, typename Action> bool call_subject(
- spirit::qi::action<Subject, Action> const &subject, Iterator &first
- , Iterator const &last, Context& context, Skipper const& skipper
- , Index &idx) const
- {
-
- typedef typename Subject::template attribute<Context, Iterator>::type attr_type;
- typedef typename fusion::result_of::value_at<Attribute,typename Index::value>::type subject_attribute;
- typedef typename traits::make_attribute<attr_type, subject_attribute> make_attribute;
-
- // create an attribute if one is not supplied
- typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, spirit::qi::domain> transform;
-
- typename make_attribute::type made_attr = make_attribute::call(fusion::at_c<Index::value>(attr));
- typename transform::type local_attr = transform::pre(made_attr);
-
- Iterator save = first;
- if (subject.subject.kwd_loop_parse(first, last, context, skipper, local_attr, NoCasePass::value ))
- {
- if(subject.subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- {
- // call the function, passing the attribute, the context.
- // The client can return false to fail parsing.
- if (traits::action_dispatch<Subject>()(subject.f, local_attr, context))
- return true;
-
- }
- }
- // reset iterators if semantic action failed the match
- // retrospectively
- first = save;
- return false;
- }
-
- // Handle unused attributes
- template <typename T> bool call(T &idx, mpl::false_) const{
-
- //if( fusion::at_c<T::value>(elements).parse_impl( first, last, context, skipper, unused, mpl::false_() ) )
- 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;
- Attribute &attr;
- };
-
-}}}}}
-
-#endif
-
-/*=============================================================================
- 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 {
-
-
- // 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>
- {
- public:
- parse_dispatcher(const Elements &elements,Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Flags &flags, Counters &counters, Attribute& 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;
- if(subject.kwd_loop_parse(first,last,context,skipper,unused, NoCasePass::value ))
- {
- if(subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- return true;
- }
- save = save;
- return false;
- }
-
- template <typename Subject, typename Index, typename Action> bool call_subject_unused(
- spirit::qi::action<Subject, Action> const &subject, Iterator &first
- , Iterator const &last, Context& context, Skipper const& skipper
- , Index &idx) const
- {
-
- typedef typename Subject::template attribute<Context, Iterator>::type attr_type;
- typedef typename traits::make_attribute<attr_type, unused_type> make_attribute;
-
- // create an attribute if one is not supplied
- typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, spirit::qi::domain> transform;
-
- typename make_attribute::type made_attr = make_attribute::call(unused);
- typename transform::type local_attr = transform::pre(made_attr);
-
- Iterator save = first;
- if (subject.subject.kwd_loop_parse(first, last, context, skipper, local_attr, NoCasePass::value ))
- {
- if(subject.subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- {
- // call the function, passing the attribute, the context.
- // The client can return false to fail parsing.
- if (traits::action_dispatch<Subject>()(subject.f, local_attr, context))
- return true;
- }
- }
- // reset iterators if semantic action failed the match
- // retrospectively
- first = 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;
- if(subject.kwd_loop_parse(first,last,context,skipper,fusion::at_c<Index::value>(attr), NoCasePass::value ))
- {
- if(subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- return true;
- }
- save = save;
- return false;
- }
-
- template <typename Subject, typename Index, typename Action> bool call_subject(
- spirit::qi::action<Subject, Action> const &subject, Iterator &first
- , Iterator const &last, Context& context, Skipper const& skipper
- , Index &idx) const
- {
-
- typedef typename Subject::template attribute<Context, Iterator>::type attr_type;
- typedef typename fusion::result_of::value_at<Attribute,typename Index::value>::type subject_attribute;
- typedef typename traits::make_attribute<attr_type, subject_attribute> make_attribute;
-
- // create an attribute if one is not supplied
- typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, spirit::qi::domain> transform;
-
- typename make_attribute::type made_attr = make_attribute::call(fusion::at_c<Index::value>(attr));
- typename transform::type local_attr = transform::pre(made_attr);
-
- Iterator save = first;
- if (subject.subject.kwd_loop_parse(first, last, context, skipper, local_attr, NoCasePass::value ))
- {
- if(subject.subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- {
- // call the function, passing the attribute, the context.
- // The client can return false to fail parsing.
- if (traits::action_dispatch<Subject>()(subject.f, local_attr, context))
- return true;
-
- }
- }
- // reset iterators if semantic action failed the match
- // retrospectively
- first = save;
- return false;
- }
-
- // Handle unused attributes
- template <typename T> bool call(T &idx, mpl::false_) const{
-
- //if( fusion::at_c<T::value>(elements).parse_impl( first, last, context, skipper, unused, mpl::false_() ) )
- 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;
- Attribute &attr;
- };
-
-}}}}}
-
-#endif
-
-/*=============================================================================
- 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 {
-
-
- // 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>
- {
- public:
- parse_dispatcher(const Elements &elements,Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Flags &flags, Counters &counters, Attribute& 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;
- if(subject.kwd_loop_parse(first,last,context,skipper,unused, NoCasePass::value ))
- {
- if(subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- return true;
- }
- save = save;
- return false;
- }
-
- template <typename Subject, typename Index, typename Action> bool call_subject_unused(
- spirit::qi::action<Subject, Action> const &subject, Iterator &first
- , Iterator const &last, Context& context, Skipper const& skipper
- , Index &idx) const
- {
-
- typedef typename Subject::template attribute<Context, Iterator>::type attr_type;
- typedef typename traits::make_attribute<attr_type, unused_type> make_attribute;
-
- // create an attribute if one is not supplied
- typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, spirit::qi::domain> transform;
-
- typename make_attribute::type made_attr = make_attribute::call(unused);
- typename transform::type local_attr = transform::pre(made_attr);
-
- Iterator save = first;
- if (subject.subject.kwd_loop_parse(first, last, context, skipper, local_attr, NoCasePass::value ))
- {
- if(subject.subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- {
- // call the function, passing the attribute, the context.
- // The client can return false to fail parsing.
- if (traits::action_dispatch<Subject>()(subject.f, local_attr, context))
- return true;
- }
- }
- // reset iterators if semantic action failed the match
- // retrospectively
- first = 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;
- if(subject.kwd_loop_parse(first,last,context,skipper,fusion::at_c<Index::value>(attr), NoCasePass::value ))
- {
- if(subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- return true;
- }
- save = save;
- return false;
- }
-
- template <typename Subject, typename Index, typename Action> bool call_subject(
- spirit::qi::action<Subject, Action> const &subject, Iterator &first
- , Iterator const &last, Context& context, Skipper const& skipper
- , Index &idx) const
- {
-
- typedef typename Subject::template attribute<Context, Iterator>::type attr_type;
- typedef typename fusion::result_of::value_at<Attribute,typename Index::value>::type subject_attribute;
- typedef typename traits::make_attribute<attr_type, subject_attribute> make_attribute;
-
- // create an attribute if one is not supplied
- typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, spirit::qi::domain> transform;
-
- typename make_attribute::type made_attr = make_attribute::call(fusion::at_c<Index::value>(attr));
- typename transform::type local_attr = transform::pre(made_attr);
-
- Iterator save = first;
- if (subject.subject.kwd_loop_parse(first, last, context, skipper, local_attr, NoCasePass::value ))
- {
- if(subject.subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- {
- // call the function, passing the attribute, the context.
- // The client can return false to fail parsing.
- if (traits::action_dispatch<Subject>()(subject.f, local_attr, context))
- return true;
-
- }
- }
- // reset iterators if semantic action failed the match
- // retrospectively
- first = save;
- return false;
- }
-
- // Handle unused attributes
- template <typename T> bool call(T &idx, mpl::false_) const{
-
- //if( fusion::at_c<T::value>(elements).parse_impl( first, last, context, skipper, unused, mpl::false_() ) )
- 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;
- Attribute &attr;
- };
-
-}}}}}
-
-#endif
-
-/*=============================================================================
- 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 {
-
-
- // 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>
- {
- public:
- parse_dispatcher(const Elements &elements,Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Flags &flags, Counters &counters, Attribute& 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;
- if(subject.kwd_loop_parse(first,last,context,skipper,unused, NoCasePass::value ))
- {
- if(subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- return true;
- }
- save = save;
- return false;
- }
-
- template <typename Subject, typename Index, typename Action> bool call_subject_unused(
- spirit::qi::action<Subject, Action> const &subject, Iterator &first
- , Iterator const &last, Context& context, Skipper const& skipper
- , Index &idx) const
- {
-
- typedef typename Subject::template attribute<Context, Iterator>::type attr_type;
- typedef typename traits::make_attribute<attr_type, unused_type> make_attribute;
-
- // create an attribute if one is not supplied
- typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, spirit::qi::domain> transform;
-
- typename make_attribute::type made_attr = make_attribute::call(unused);
- typename transform::type local_attr = transform::pre(made_attr);
-
- Iterator save = first;
- if (subject.subject.kwd_loop_parse(first, last, context, skipper, local_attr, NoCasePass::value ))
- {
- if(subject.subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- {
- // call the function, passing the attribute, the context.
- // The client can return false to fail parsing.
- if (traits::action_dispatch<Subject>()(subject.f, local_attr, context))
- return true;
- }
- }
- // reset iterators if semantic action failed the match
- // retrospectively
- first = 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;
- if(subject.kwd_loop_parse(first,last,context,skipper,fusion::at_c<Index::value>(attr), NoCasePass::value ))
- {
- if(subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- return true;
- }
- save = save;
- return false;
- }
-
- template <typename Subject, typename Index, typename Action> bool call_subject(
- spirit::qi::action<Subject, Action> const &subject, Iterator &first
- , Iterator const &last, Context& context, Skipper const& skipper
- , Index &idx) const
- {
-
- typedef typename Subject::template attribute<Context, Iterator>::type attr_type;
- typedef typename fusion::result_of::value_at<Attribute,typename Index::value>::type subject_attribute;
- typedef typename traits::make_attribute<attr_type, subject_attribute> make_attribute;
-
- // create an attribute if one is not supplied
- typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, spirit::qi::domain> transform;
-
- typename make_attribute::type made_attr = make_attribute::call(fusion::at_c<Index::value>(attr));
- typename transform::type local_attr = transform::pre(made_attr);
-
- Iterator save = first;
- if (subject.subject.kwd_loop_parse(first, last, context, skipper, local_attr, NoCasePass::value ))
- {
- if(subject.subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- {
- // call the function, passing the attribute, the context.
- // The client can return false to fail parsing.
- if (traits::action_dispatch<Subject>()(subject.f, local_attr, context))
- return true;
-
- }
- }
- // reset iterators if semantic action failed the match
- // retrospectively
- first = save;
- return false;
- }
-
- // Handle unused attributes
- template <typename T> bool call(T &idx, mpl::false_) const{
-
- //if( fusion::at_c<T::value>(elements).parse_impl( first, last, context, skipper, unused, mpl::false_() ) )
- 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;
- Attribute &attr;
- };
-
-}}}}}
-
-#endif
-
-/*=============================================================================
- 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 {
-
-
- // 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>
- {
- public:
- parse_dispatcher(const Elements &elements,Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Flags &flags, Counters &counters, Attribute& 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;
- if(subject.kwd_loop_parse(first,last,context,skipper,unused, NoCasePass::value ))
- {
- if(subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- return true;
- }
- save = save;
- return false;
- }
-
- template <typename Subject, typename Index, typename Action> bool call_subject_unused(
- spirit::qi::action<Subject, Action> const &subject, Iterator &first
- , Iterator const &last, Context& context, Skipper const& skipper
- , Index &idx) const
- {
-
- typedef typename Subject::template attribute<Context, Iterator>::type attr_type;
- typedef typename traits::make_attribute<attr_type, unused_type> make_attribute;
-
- // create an attribute if one is not supplied
- typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, spirit::qi::domain> transform;
-
- typename make_attribute::type made_attr = make_attribute::call(unused);
- typename transform::type local_attr = transform::pre(made_attr);
-
- Iterator save = first;
- if (subject.subject.kwd_loop_parse(first, last, context, skipper, local_attr, NoCasePass::value ))
- {
- if(subject.subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- {
- // call the function, passing the attribute, the context.
- // The client can return false to fail parsing.
- if (traits::action_dispatch<Subject>()(subject.f, local_attr, context))
- return true;
- }
- }
- // reset iterators if semantic action failed the match
- // retrospectively
- first = 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;
- if(subject.kwd_loop_parse(first,last,context,skipper,fusion::at_c<Index::value>(attr), NoCasePass::value ))
- {
- if(subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- return true;
- }
- save = save;
- return false;
- }
-
- template <typename Subject, typename Index, typename Action> bool call_subject(
- spirit::qi::action<Subject, Action> const &subject, Iterator &first
- , Iterator const &last, Context& context, Skipper const& skipper
- , Index &idx) const
- {
-
- typedef typename Subject::template attribute<Context, Iterator>::type attr_type;
- typedef typename fusion::result_of::value_at<Attribute,typename Index::value>::type subject_attribute;
- typedef typename traits::make_attribute<attr_type, subject_attribute> make_attribute;
-
- // create an attribute if one is not supplied
- typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, spirit::qi::domain> transform;
-
- typename make_attribute::type made_attr = make_attribute::call(fusion::at_c<Index::value>(attr));
- typename transform::type local_attr = transform::pre(made_attr);
-
- Iterator save = first;
- if (subject.subject.kwd_loop_parse(first, last, context, skipper, local_attr, NoCasePass::value ))
- {
- if(subject.subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- {
- // call the function, passing the attribute, the context.
- // The client can return false to fail parsing.
- if (traits::action_dispatch<Subject>()(subject.f, local_attr, context))
- return true;
-
- }
- }
- // reset iterators if semantic action failed the match
- // retrospectively
- first = save;
- return false;
- }
-
- // Handle unused attributes
- template <typename T> bool call(T &idx, mpl::false_) const{
-
- //if( fusion::at_c<T::value>(elements).parse_impl( first, last, context, skipper, unused, mpl::false_() ) )
- 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;
- Attribute &attr;
- };
-
-}}}}}
-
-#endif
-
-/*=============================================================================
- 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 {
-
-
- // 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>
- {
- public:
- parse_dispatcher(const Elements &elements,Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Flags &flags, Counters &counters, Attribute& 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;
- if(subject.kwd_loop_parse(first,last,context,skipper,unused, NoCasePass::value ))
- {
- if(subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- return true;
- }
- save = save;
- return false;
- }
-
- template <typename Subject, typename Index, typename Action> bool call_subject_unused(
- spirit::qi::action<Subject, Action> const &subject, Iterator &first
- , Iterator const &last, Context& context, Skipper const& skipper
- , Index &idx) const
- {
-
- typedef typename Subject::template attribute<Context, Iterator>::type attr_type;
- typedef typename traits::make_attribute<attr_type, unused_type> make_attribute;
-
- // create an attribute if one is not supplied
- typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, spirit::qi::domain> transform;
-
- typename make_attribute::type made_attr = make_attribute::call(unused);
- typename transform::type local_attr = transform::pre(made_attr);
-
- Iterator save = first;
- if (subject.subject.kwd_loop_parse(first, last, context, skipper, local_attr, NoCasePass::value ))
- {
- if(subject.subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- {
- // call the function, passing the attribute, the context.
- // The client can return false to fail parsing.
- if (traits::action_dispatch<Subject>()(subject.f, local_attr, context))
- return true;
- }
- }
- // reset iterators if semantic action failed the match
- // retrospectively
- first = 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;
- if(subject.kwd_loop_parse(first,last,context,skipper,fusion::at_c<Index::value>(attr), NoCasePass::value ))
- {
- if(subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- return true;
- }
- save = save;
- return false;
- }
-
- template <typename Subject, typename Index, typename Action> bool call_subject(
- spirit::qi::action<Subject, Action> const &subject, Iterator &first
- , Iterator const &last, Context& context, Skipper const& skipper
- , Index &idx) const
- {
-
- typedef typename Subject::template attribute<Context, Iterator>::type attr_type;
- typedef typename fusion::result_of::value_at<Attribute,typename Index::value>::type subject_attribute;
- typedef typename traits::make_attribute<attr_type, subject_attribute> make_attribute;
-
- // create an attribute if one is not supplied
- typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, spirit::qi::domain> transform;
-
- typename make_attribute::type made_attr = make_attribute::call(fusion::at_c<Index::value>(attr));
- typename transform::type local_attr = transform::pre(made_attr);
-
- Iterator save = first;
- if (subject.subject.kwd_loop_parse(first, last, context, skipper, local_attr, NoCasePass::value ))
- {
- if(subject.subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- {
- // call the function, passing the attribute, the context.
- // The client can return false to fail parsing.
- if (traits::action_dispatch<Subject>()(subject.f, local_attr, context))
- return true;
-
- }
- }
- // reset iterators if semantic action failed the match
- // retrospectively
- first = save;
- return false;
- }
-
- // Handle unused attributes
- template <typename T> bool call(T &idx, mpl::false_) const{
-
- //if( fusion::at_c<T::value>(elements).parse_impl( first, last, context, skipper, unused, mpl::false_() ) )
- 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;
- Attribute &attr;
- };
-
-}}}}}
-
-#endif
-
-/*=============================================================================
- 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 {
-
-
- // 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>
- {
- public:
- parse_dispatcher(const Elements &elements,Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Flags &flags, Counters &counters, Attribute& 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;
- if(subject.kwd_loop_parse(first,last,context,skipper,unused, NoCasePass::value ))
- {
- if(subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- return true;
- }
- save = save;
- return false;
- }
-
- template <typename Subject, typename Index, typename Action> bool call_subject_unused(
- spirit::qi::action<Subject, Action> const &subject, Iterator &first
- , Iterator const &last, Context& context, Skipper const& skipper
- , Index &idx) const
- {
-
- typedef typename Subject::template attribute<Context, Iterator>::type attr_type;
- typedef typename traits::make_attribute<attr_type, unused_type> make_attribute;
-
- // create an attribute if one is not supplied
- typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, spirit::qi::domain> transform;
-
- typename make_attribute::type made_attr = make_attribute::call(unused);
- typename transform::type local_attr = transform::pre(made_attr);
-
- Iterator save = first;
- if (subject.subject.kwd_loop_parse(first, last, context, skipper, local_attr, NoCasePass::value ))
- {
- if(subject.subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- {
- // call the function, passing the attribute, the context.
- // The client can return false to fail parsing.
- if (traits::action_dispatch<Subject>()(subject.f, local_attr, context))
- return true;
- }
- }
- // reset iterators if semantic action failed the match
- // retrospectively
- first = 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;
- if(subject.kwd_loop_parse(first,last,context,skipper,fusion::at_c<Index::value>(attr), NoCasePass::value ))
- {
- if(subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- return true;
- }
- save = save;
- return false;
- }
-
- template <typename Subject, typename Index, typename Action> bool call_subject(
- spirit::qi::action<Subject, Action> const &subject, Iterator &first
- , Iterator const &last, Context& context, Skipper const& skipper
- , Index &idx) const
- {
-
- typedef typename Subject::template attribute<Context, Iterator>::type attr_type;
- typedef typename fusion::result_of::value_at<Attribute,typename Index::value>::type subject_attribute;
- typedef typename traits::make_attribute<attr_type, subject_attribute> make_attribute;
-
- // create an attribute if one is not supplied
- typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, spirit::qi::domain> transform;
-
- typename make_attribute::type made_attr = make_attribute::call(fusion::at_c<Index::value>(attr));
- typename transform::type local_attr = transform::pre(made_attr);
-
- Iterator save = first;
- if (subject.subject.kwd_loop_parse(first, last, context, skipper, local_attr, NoCasePass::value ))
- {
- if(subject.subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- {
- // call the function, passing the attribute, the context.
- // The client can return false to fail parsing.
- if (traits::action_dispatch<Subject>()(subject.f, local_attr, context))
- return true;
-
- }
- }
- // reset iterators if semantic action failed the match
- // retrospectively
- first = save;
- return false;
- }
-
- // Handle unused attributes
- template <typename T> bool call(T &idx, mpl::false_) const{
-
- //if( fusion::at_c<T::value>(elements).parse_impl( first, last, context, skipper, unused, mpl::false_() ) )
- 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;
- Attribute &attr;
- };
-
-}}}}}
-
-#endif
-
-/*=============================================================================
- 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 {
-
-
- // 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>
+ // This helper class enables jumping over intermediate directives
+ // down the kwd parser iteration count checking policy
+ struct register_successful_parse
{
- public:
- parse_dispatcher(const Elements &elements,Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Flags &flags, Counters &counters, Attribute& 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;
- if(subject.kwd_loop_parse(first,last,context,skipper,unused, NoCasePass::value ))
- {
- if(subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- return true;
- }
- save = save;
- return false;
- }
-
- template <typename Subject, typename Index, typename Action> bool call_subject_unused(
- spirit::qi::action<Subject, Action> const &subject, Iterator &first
- , Iterator const &last, Context& context, Skipper const& skipper
- , Index &idx) const
- {
-
- typedef typename Subject::template attribute<Context, Iterator>::type attr_type;
- typedef typename traits::make_attribute<attr_type, unused_type> make_attribute;
-
- // create an attribute if one is not supplied
- typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, spirit::qi::domain> transform;
-
- typename make_attribute::type made_attr = make_attribute::call(unused);
- typename transform::type local_attr = transform::pre(made_attr);
-
- Iterator save = first;
- if (subject.subject.kwd_loop_parse(first, last, context, skipper, local_attr, NoCasePass::value ))
- {
- if(subject.subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- {
- // call the function, passing the attribute, the context.
- // The client can return false to fail parsing.
- if (traits::action_dispatch<Subject>()(subject.f, local_attr, context))
- return true;
- }
- }
- // reset iterators if semantic action failed the match
- // retrospectively
- first = 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;
- if(subject.kwd_loop_parse(first,last,context,skipper,fusion::at_c<Index::value>(attr), NoCasePass::value ))
- {
- if(subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- return true;
- }
- save = save;
- return false;
- }
-
- template <typename Subject, typename Index, typename Action> bool call_subject(
- spirit::qi::action<Subject, Action> const &subject, Iterator &first
- , Iterator const &last, Context& context, Skipper const& skipper
- , Index &idx) const
+ template <typename Subject>
+ static bool call(Subject const &subject,bool &flag, int &counter)
{
-
- typedef typename Subject::template attribute<Context, Iterator>::type attr_type;
- typedef typename fusion::result_of::value_at<Attribute,typename Index::value>::type subject_attribute;
- typedef typename traits::make_attribute<attr_type, subject_attribute> make_attribute;
-
- // create an attribute if one is not supplied
- typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, spirit::qi::domain> transform;
-
- typename make_attribute::type made_attr = make_attribute::call(fusion::at_c<Index::value>(attr));
- typename transform::type local_attr = transform::pre(made_attr);
-
- Iterator save = first;
- if (subject.subject.kwd_loop_parse(first, last, context, skipper, local_attr, NoCasePass::value ))
- {
- if(subject.subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- {
- // call the function, passing the attribute, the context.
- // The client can return false to fail parsing.
- if (traits::action_dispatch<Subject>()(subject.f, local_attr, context))
- return true;
-
- }
- }
- // reset iterators if semantic action failed the match
- // retrospectively
- first = save;
- return false;
- }
-
- // Handle unused attributes
- template <typename T> bool call(T &idx, mpl::false_) const{
-
- //if( fusion::at_c<T::value>(elements).parse_impl( first, last, context, skipper, unused, mpl::false_() ) )
- 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;
- Attribute &attr;
- };
-
-}}}}}
-
-#endif
-
-/*=============================================================================
- 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 {
-
-
- // 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>
- {
- public:
- parse_dispatcher(const Elements &elements,Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Flags &flags, Counters &counters, Attribute& 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());
-
+ return subject.iter.register_successful_parse(flag,counter);
}
-
- 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;
- if(subject.kwd_loop_parse(first,last,context,skipper,unused, NoCasePass::value ))
- {
- if(subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- return true;
- }
- save = save;
- return false;
- }
-
- template <typename Subject, typename Index, typename Action> bool call_subject_unused(
- spirit::qi::action<Subject, Action> const &subject, Iterator &first
- , Iterator const &last, Context& context, Skipper const& skipper
- , Index &idx) const
- {
-
- typedef typename Subject::template attribute<Context, Iterator>::type attr_type;
- typedef typename traits::make_attribute<attr_type, unused_type> make_attribute;
-
- // create an attribute if one is not supplied
- typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, spirit::qi::domain> transform;
-
- typename make_attribute::type made_attr = make_attribute::call(unused);
- typename transform::type local_attr = transform::pre(made_attr);
-
- Iterator save = first;
- if (subject.subject.kwd_loop_parse(first, last, context, skipper, local_attr, NoCasePass::value ))
- {
- if(subject.subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- {
- // call the function, passing the attribute, the context.
- // The client can return false to fail parsing.
- if (traits::action_dispatch<Subject>()(subject.f, local_attr, context))
- return true;
- }
- }
- // reset iterators if semantic action failed the match
- // retrospectively
- first = 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;
- if(subject.kwd_loop_parse(first,last,context,skipper,fusion::at_c<Index::value>(attr), NoCasePass::value ))
- {
- if(subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- return true;
- }
- save = save;
- return false;
- }
-
- template <typename Subject, typename Index, typename Action> bool call_subject(
- spirit::qi::action<Subject, Action> const &subject, Iterator &first
- , Iterator const &last, Context& context, Skipper const& skipper
- , Index &idx) const
+ template <typename Subject, typename Action>
+ static bool call(spirit::qi::action<Subject, Action> const &subject,bool &flag, int &counter)
{
-
- typedef typename Subject::template attribute<Context, Iterator>::type attr_type;
- typedef typename fusion::result_of::value_at<Attribute,typename Index::value>::type subject_attribute;
- typedef typename traits::make_attribute<attr_type, subject_attribute> make_attribute;
-
- // create an attribute if one is not supplied
- typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, spirit::qi::domain> transform;
-
- typename make_attribute::type made_attr = make_attribute::call(fusion::at_c<Index::value>(attr));
- typename transform::type local_attr = transform::pre(made_attr);
-
- Iterator save = first;
- if (subject.subject.kwd_loop_parse(first, last, context, skipper, local_attr, NoCasePass::value ))
- {
- if(subject.subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- {
- // call the function, passing the attribute, the context.
- // The client can return false to fail parsing.
- if (traits::action_dispatch<Subject>()(subject.f, local_attr, context))
- return true;
-
- }
- }
- // reset iterators if semantic action failed the match
- // retrospectively
- first = save;
- return false;
- }
-
- // Handle unused attributes
- template <typename T> bool call(T &idx, mpl::false_) const{
-
- //if( fusion::at_c<T::value>(elements).parse_impl( first, last, context, skipper, unused, mpl::false_() ) )
- return call_subject_unused(fusion::at_c<T::value>(elements), first, last, context, skipper, idx );
+ return subject.subject.iter.register_successful_parse(flag,counter);
}
- // 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);
+ 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);
}
-
- const Elements &elements;
- Iterator &first;
- const Iterator &last;
- Context & context;
- const Skipper &skipper;
- Flags &flags;
- Counters &counters;
- Attribute &attr;
};
-
-}}}}}
-
-#endif
-
-/*=============================================================================
- 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 {
-
-
// 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
@@ -2840,7 +54,6 @@
template<typename T> bool operator()(T& idx) const
{
return call(idx,typename traits::not_is_unused<Attribute>::type());
-
}
template <typename Subject,typename Index>
@@ -2850,47 +63,16 @@
, Index& idx ) const
{
Iterator save = first;
- if(subject.kwd_loop_parse(first,last,context,skipper,unused, NoCasePass::value ))
+ skipper_keyword_marker<Skipper,NoCasePass> marked_skipper(skipper,flags[Index::value],counters[Index::value]);
+
+ if(subject.parse(first,last,context,marked_skipper,unused))
{
- if(subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
return true;
}
save = save;
return false;
}
- template <typename Subject, typename Index, typename Action> bool call_subject_unused(
- spirit::qi::action<Subject, Action> const &subject, Iterator &first
- , Iterator const &last, Context& context, Skipper const& skipper
- , Index &idx) const
- {
-
- typedef typename Subject::template attribute<Context, Iterator>::type attr_type;
- typedef typename traits::make_attribute<attr_type, unused_type> make_attribute;
-
- // create an attribute if one is not supplied
- typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, spirit::qi::domain> transform;
-
- typename make_attribute::type made_attr = make_attribute::call(unused);
- typename transform::type local_attr = transform::pre(made_attr);
-
- Iterator save = first;
- if (subject.subject.kwd_loop_parse(first, last, context, skipper, local_attr, NoCasePass::value ))
- {
- if(subject.subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- {
- // call the function, passing the attribute, the context.
- // The client can return false to fail parsing.
- if (traits::action_dispatch<Subject>()(subject.f, local_attr, context))
- return true;
- }
- }
- // reset iterators if semantic action failed the match
- // retrospectively
- first = save;
- return false;
- }
template <typename Subject,typename Index>
bool call_subject(
@@ -2898,55 +80,19 @@
, Context& context, Skipper const& skipper
, Index& idx ) const
{
+
Iterator save = first;
- if(subject.kwd_loop_parse(first,last,context,skipper,fusion::at_c<Index::value>(attr), NoCasePass::value ))
+ 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)))
{
- if(subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
return true;
}
save = save;
return false;
- }
-
- template <typename Subject, typename Index, typename Action> bool call_subject(
- spirit::qi::action<Subject, Action> const &subject, Iterator &first
- , Iterator const &last, Context& context, Skipper const& skipper
- , Index &idx) const
- {
-
- typedef typename Subject::template attribute<Context, Iterator>::type attr_type;
- typedef typename fusion::result_of::value_at<Attribute,typename Index::value>::type subject_attribute;
- typedef typename traits::make_attribute<attr_type, subject_attribute> make_attribute;
-
- // create an attribute if one is not supplied
- typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, spirit::qi::domain> transform;
-
- typename make_attribute::type made_attr = make_attribute::call(fusion::at_c<Index::value>(attr));
- typename transform::type local_attr = transform::pre(made_attr);
-
- Iterator save = first;
- if (subject.subject.kwd_loop_parse(first, last, context, skipper, local_attr, NoCasePass::value ))
- {
- if(subject.subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- {
- // call the function, passing the attribute, the context.
- // The client can return false to fail parsing.
- if (traits::action_dispatch<Subject>()(subject.f, local_attr, context))
- return true;
+ }
- }
- }
- // reset iterators if semantic action failed the match
- // retrospectively
- first = save;
- return false;
- }
-
// Handle unused attributes
- template <typename T> bool call(T &idx, mpl::false_) const{
-
- //if( fusion::at_c<T::value>(elements).parse_impl( first, last, context, skipper, unused, mpl::false_() ) )
+ 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
@@ -2967,4 +113,3 @@
}}}}}
#endif
-
Modified: trunk/boost/spirit/repository/home/qi/operator/keywords.hpp
==============================================================================
--- trunk/boost/spirit/repository/home/qi/operator/keywords.hpp (original)
+++ trunk/boost/spirit/repository/home/qi/operator/keywords.hpp 2011-03-19 20:02:11 EDT (Sat, 19 Mar 2011)
@@ -20,6 +20,7 @@
#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>
@@ -27,6 +28,7 @@
#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>
@@ -71,6 +73,9 @@
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> >
@@ -160,6 +165,11 @@
{
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>
@@ -247,6 +257,11 @@
{
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>
@@ -379,7 +394,21 @@
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;
@@ -609,9596 +638,3 @@
#endif
-/*=============================================================================
- 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/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/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/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>
-
-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> {};
-
- // 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, mpl::identity, Iterator>::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;
- };
-
- // 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;
- };
-
- // 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, is_same<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;
-
- typedef typename kwd_count::asdfa debug;
-
- // 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;
- }
-
-
- shared_ptr<keywords_type> lookup;
- flags_type & flags;
- };
-
-
-
- // 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 Iterator ,typename Context ,typename Skipper
- ,typename Flags ,typename Counters ,typename Attribute>
- class parse_dispatcher
- : public boost::static_visitor<bool>
- {
- public:
- parse_dispatcher(const Elements &elements,Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Flags &flags, Counters &counters, Attribute& attr, bool case_insensitive_pass) :
- elements(elements), first(first), last(last)
- , context(context), skipper(skipper)
- , flags(flags),counters(counters), attr(attr)
- , case_insensitive_pass(case_insensitive_pass) {}
-
- template<typename T> bool operator()(T& idx) const
- {
- return call(idx,case_insensitive_pass,typename traits::not_is_unused<Attribute>::type());
-
- }
- // Handle unused attributes
- template <typename T> bool call(T &idx, bool case_insensitive_pass, mpl::false_) const{
- return fusion::at_c<T::value>(elements).parse(
- first
- ,last
- ,context
- ,skipper
- ,unused
- ,flags[T::value],counters[T::value]
- ,case_insensitive_pass
- );
- }
- // Handle normal attributes
- template <typename T> bool call(T &idx,bool case_insensitive_pass, mpl::true_) const{
- return fusion::at_c<T::value>(elements).parse(
- first
- ,last
- ,context
- ,skipper
- ,fusion::at_c<T::value>(attr)
- ,flags[T::value],counters[T::value]
- ,case_insensitive_pass
- );
- }
-
-
- const Elements &elements;
- Iterator &first;
- const Iterator &last;
- Context & context;
- const Skipper &skipper;
- Flags &flags;
- Counters &counters;
- Attribute &attr;
- bool case_insensitive_pass;
- };
-
- 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 parse_dispatcher<Iterator, Context, Skipper
- , flags_type, counters_type
- , typename traits::wrap_if_not_tuple<Attribute>::type
- > parser_visitor_type;
- parser_visitor_type parse_visitor(elements, first, last
- , context, skipper, flags
- , counters, attr, false);
-
- // 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 parse_dispatcher<Iterator, Context, Skipper
- , flags_type, counters_type
- , typename traits::wrap_if_not_tuple<Attribute>::type
- > parser_visitor_type;
-
- parser_visitor_type parse_visitor(elements,first,last
- ,context,skipper,flags,counters,attr,false);
- parser_visitor_type no_case_parse_visitor(elements,first,last
- ,context,skipper,flags,counters,attr,true);
-
- // 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
-
-/*=============================================================================
- 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/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/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/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> {};
-
- // 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, mpl::identity, Iterator>::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;
- };
-
- // 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;
- };
-
- // 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;
- }
-
-
- 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
-
-/*=============================================================================
- 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/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/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/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>
-
-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> {};
-
- // 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, mpl::identity, Iterator>::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;
- };
-
- // 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;
- };
-
- // 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, is_same<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;
-
- typedef typename kwd_count::asdfa debug;
-
- // 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;
- }
-
-
- shared_ptr<keywords_type> lookup;
- flags_type & flags;
- };
-
-
-
- // 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 Iterator ,typename Context ,typename Skipper
- ,typename Flags ,typename Counters ,typename Attribute>
- class parse_dispatcher
- : public boost::static_visitor<bool>
- {
- public:
- parse_dispatcher(const Elements &elements,Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Flags &flags, Counters &counters, Attribute& attr, bool case_insensitive_pass) :
- elements(elements), first(first), last(last)
- , context(context), skipper(skipper)
- , flags(flags),counters(counters), attr(attr)
- , case_insensitive_pass(case_insensitive_pass) {}
-
- template<typename T> bool operator()(T& idx) const
- {
- return call(idx,case_insensitive_pass,typename traits::not_is_unused<Attribute>::type());
-
- }
- // Handle unused attributes
- template <typename T> bool call(T &idx, bool case_insensitive_pass, mpl::false_) const{
- return fusion::at_c<T::value>(elements).parse(
- first
- ,last
- ,context
- ,skipper
- ,unused
- ,flags[T::value],counters[T::value]
- ,case_insensitive_pass
- );
- }
- // Handle normal attributes
- template <typename T> bool call(T &idx,bool case_insensitive_pass, mpl::true_) const{
- return fusion::at_c<T::value>(elements).parse(
- first
- ,last
- ,context
- ,skipper
- ,fusion::at_c<T::value>(attr)
- ,flags[T::value],counters[T::value]
- ,case_insensitive_pass
- );
- }
-
-
- const Elements &elements;
- Iterator &first;
- const Iterator &last;
- Context & context;
- const Skipper &skipper;
- Flags &flags;
- Counters &counters;
- Attribute &attr;
- bool case_insensitive_pass;
- };
-
- 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 parse_dispatcher<Iterator, Context, Skipper
- , flags_type, counters_type
- , typename traits::wrap_if_not_tuple<Attribute>::type
- > parser_visitor_type;
- parser_visitor_type parse_visitor(elements, first, last
- , context, skipper, flags
- , counters, attr, false);
-
- // 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 parse_dispatcher<Iterator, Context, Skipper
- , flags_type, counters_type
- , typename traits::wrap_if_not_tuple<Attribute>::type
- > parser_visitor_type;
-
- parser_visitor_type parse_visitor(elements,first,last
- ,context,skipper,flags,counters,attr,false);
- parser_visitor_type no_case_parse_visitor(elements,first,last
- ,context,skipper,flags,counters,attr,true);
-
- // 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
-
-/*=============================================================================
- 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/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/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> {};
-
- // 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;
- };
-
- // 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;
- };
-
- // 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;
- }
-
-
- 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
-
-/*=============================================================================
- 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/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/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/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>
-
-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> {};
-
- // 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, mpl::identity, Iterator>::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;
- };
-
- // 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;
- };
-
- // 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, is_same<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;
-
- typedef typename kwd_count::asdfa debug;
-
- // 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;
- }
-
-
- shared_ptr<keywords_type> lookup;
- flags_type & flags;
- };
-
-
-
- // 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 Iterator ,typename Context ,typename Skipper
- ,typename Flags ,typename Counters ,typename Attribute>
- class parse_dispatcher
- : public boost::static_visitor<bool>
- {
- public:
- parse_dispatcher(const Elements &elements,Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Flags &flags, Counters &counters, Attribute& attr, bool case_insensitive_pass) :
- elements(elements), first(first), last(last)
- , context(context), skipper(skipper)
- , flags(flags),counters(counters), attr(attr)
- , case_insensitive_pass(case_insensitive_pass) {}
-
- template<typename T> bool operator()(T& idx) const
- {
- return call(idx,case_insensitive_pass,typename traits::not_is_unused<Attribute>::type());
-
- }
- // Handle unused attributes
- template <typename T> bool call(T &idx, bool case_insensitive_pass, mpl::false_) const{
- return fusion::at_c<T::value>(elements).parse(
- first
- ,last
- ,context
- ,skipper
- ,unused
- ,flags[T::value],counters[T::value]
- ,case_insensitive_pass
- );
- }
- // Handle normal attributes
- template <typename T> bool call(T &idx,bool case_insensitive_pass, mpl::true_) const{
- return fusion::at_c<T::value>(elements).parse(
- first
- ,last
- ,context
- ,skipper
- ,fusion::at_c<T::value>(attr)
- ,flags[T::value],counters[T::value]
- ,case_insensitive_pass
- );
- }
-
-
- const Elements &elements;
- Iterator &first;
- const Iterator &last;
- Context & context;
- const Skipper &skipper;
- Flags &flags;
- Counters &counters;
- Attribute &attr;
- bool case_insensitive_pass;
- };
-
- 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 parse_dispatcher<Iterator, Context, Skipper
- , flags_type, counters_type
- , typename traits::wrap_if_not_tuple<Attribute>::type
- > parser_visitor_type;
- parser_visitor_type parse_visitor(elements, first, last
- , context, skipper, flags
- , counters, attr, false);
-
- // 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 parse_dispatcher<Iterator, Context, Skipper
- , flags_type, counters_type
- , typename traits::wrap_if_not_tuple<Attribute>::type
- > parser_visitor_type;
-
- parser_visitor_type parse_visitor(elements,first,last
- ,context,skipper,flags,counters,attr,false);
- parser_visitor_type no_case_parse_visitor(elements,first,last
- ,context,skipper,flags,counters,attr,true);
-
- // 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
-
-/*=============================================================================
- 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/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/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/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> {};
-
- // 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, mpl::identity, Iterator>::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;
- };
-
- // 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;
- };
-
- // 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;
- }
-
-
- 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
-
-/*=============================================================================
- 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/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/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/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>
-
-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> {};
-
- // 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, mpl::identity, Iterator>::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;
- };
-
- // 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;
- };
-
- // 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, is_same<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;
-
- typedef typename kwd_count::asdfa debug;
-
- // 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;
- }
-
-
- shared_ptr<keywords_type> lookup;
- flags_type & flags;
- };
-
-
-
- // 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 Iterator ,typename Context ,typename Skipper
- ,typename Flags ,typename Counters ,typename Attribute>
- class parse_dispatcher
- : public boost::static_visitor<bool>
- {
- public:
- parse_dispatcher(const Elements &elements,Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Flags &flags, Counters &counters, Attribute& attr, bool case_insensitive_pass) :
- elements(elements), first(first), last(last)
- , context(context), skipper(skipper)
- , flags(flags),counters(counters), attr(attr)
- , case_insensitive_pass(case_insensitive_pass) {}
-
- template<typename T> bool operator()(T& idx) const
- {
- return call(idx,case_insensitive_pass,typename traits::not_is_unused<Attribute>::type());
-
- }
- // Handle unused attributes
- template <typename T> bool call(T &idx, bool case_insensitive_pass, mpl::false_) const{
- return fusion::at_c<T::value>(elements).parse(
- first
- ,last
- ,context
- ,skipper
- ,unused
- ,flags[T::value],counters[T::value]
- ,case_insensitive_pass
- );
- }
- // Handle normal attributes
- template <typename T> bool call(T &idx,bool case_insensitive_pass, mpl::true_) const{
- return fusion::at_c<T::value>(elements).parse(
- first
- ,last
- ,context
- ,skipper
- ,fusion::at_c<T::value>(attr)
- ,flags[T::value],counters[T::value]
- ,case_insensitive_pass
- );
- }
-
-
- const Elements &elements;
- Iterator &first;
- const Iterator &last;
- Context & context;
- const Skipper &skipper;
- Flags &flags;
- Counters &counters;
- Attribute &attr;
- bool case_insensitive_pass;
- };
-
- 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 parse_dispatcher<Iterator, Context, Skipper
- , flags_type, counters_type
- , typename traits::wrap_if_not_tuple<Attribute>::type
- > parser_visitor_type;
- parser_visitor_type parse_visitor(elements, first, last
- , context, skipper, flags
- , counters, attr, false);
-
- // 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 parse_dispatcher<Iterator, Context, Skipper
- , flags_type, counters_type
- , typename traits::wrap_if_not_tuple<Attribute>::type
- > parser_visitor_type;
-
- parser_visitor_type parse_visitor(elements,first,last
- ,context,skipper,flags,counters,attr,false);
- parser_visitor_type no_case_parse_visitor(elements,first,last
- ,context,skipper,flags,counters,attr,true);
-
- // 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
-
-/*=============================================================================
- 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/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/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> {};
-
- // 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;
- };
-
- // 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;
- };
-
- // 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;
- }
-
-
- 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
-
-/*=============================================================================
- 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/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/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/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>
-
-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> {};
-
- // 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, mpl::identity, Iterator>::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;
- };
-
- // 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;
- };
-
- // 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, is_same<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;
-
- typedef typename kwd_count::asdfa debug;
-
- // 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;
- }
-
-
- shared_ptr<keywords_type> lookup;
- flags_type & flags;
- };
-
-
-
- // 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 Iterator ,typename Context ,typename Skipper
- ,typename Flags ,typename Counters ,typename Attribute>
- class parse_dispatcher
- : public boost::static_visitor<bool>
- {
- public:
- parse_dispatcher(const Elements &elements,Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Flags &flags, Counters &counters, Attribute& attr, bool case_insensitive_pass) :
- elements(elements), first(first), last(last)
- , context(context), skipper(skipper)
- , flags(flags),counters(counters), attr(attr)
- , case_insensitive_pass(case_insensitive_pass) {}
-
- template<typename T> bool operator()(T& idx) const
- {
- return call(idx,case_insensitive_pass,typename traits::not_is_unused<Attribute>::type());
-
- }
- // Handle unused attributes
- template <typename T> bool call(T &idx, bool case_insensitive_pass, mpl::false_) const{
- return fusion::at_c<T::value>(elements).parse(
- first
- ,last
- ,context
- ,skipper
- ,unused
- ,flags[T::value],counters[T::value]
- ,case_insensitive_pass
- );
- }
- // Handle normal attributes
- template <typename T> bool call(T &idx,bool case_insensitive_pass, mpl::true_) const{
- return fusion::at_c<T::value>(elements).parse(
- first
- ,last
- ,context
- ,skipper
- ,fusion::at_c<T::value>(attr)
- ,flags[T::value],counters[T::value]
- ,case_insensitive_pass
- );
- }
-
-
- const Elements &elements;
- Iterator &first;
- const Iterator &last;
- Context & context;
- const Skipper &skipper;
- Flags &flags;
- Counters &counters;
- Attribute &attr;
- bool case_insensitive_pass;
- };
-
- 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 parse_dispatcher<Iterator, Context, Skipper
- , flags_type, counters_type
- , typename traits::wrap_if_not_tuple<Attribute>::type
- > parser_visitor_type;
- parser_visitor_type parse_visitor(elements, first, last
- , context, skipper, flags
- , counters, attr, false);
-
- // 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 parse_dispatcher<Iterator, Context, Skipper
- , flags_type, counters_type
- , typename traits::wrap_if_not_tuple<Attribute>::type
- > parser_visitor_type;
-
- parser_visitor_type parse_visitor(elements,first,last
- ,context,skipper,flags,counters,attr,false);
- parser_visitor_type no_case_parse_visitor(elements,first,last
- ,context,skipper,flags,counters,attr,true);
-
- // 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
-
-/*=============================================================================
- 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/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/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/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> {};
-
- // 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, mpl::identity, Iterator>::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;
- };
-
- // 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;
- };
-
- // 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;
- }
-
-
- 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
-
-/*=============================================================================
- 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/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/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/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>
-
-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> {};
-
- // 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, mpl::identity, Iterator>::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;
- };
-
- // 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;
- };
-
- // 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, is_same<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;
-
- typedef typename kwd_count::asdfa debug;
-
- // 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;
- }
-
-
- shared_ptr<keywords_type> lookup;
- flags_type & flags;
- };
-
-
-
- // 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 Iterator ,typename Context ,typename Skipper
- ,typename Flags ,typename Counters ,typename Attribute>
- class parse_dispatcher
- : public boost::static_visitor<bool>
- {
- public:
- parse_dispatcher(const Elements &elements,Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Flags &flags, Counters &counters, Attribute& attr, bool case_insensitive_pass) :
- elements(elements), first(first), last(last)
- , context(context), skipper(skipper)
- , flags(flags),counters(counters), attr(attr)
- , case_insensitive_pass(case_insensitive_pass) {}
-
- template<typename T> bool operator()(T& idx) const
- {
- return call(idx,case_insensitive_pass,typename traits::not_is_unused<Attribute>::type());
-
- }
- // Handle unused attributes
- template <typename T> bool call(T &idx, bool case_insensitive_pass, mpl::false_) const{
- return fusion::at_c<T::value>(elements).parse(
- first
- ,last
- ,context
- ,skipper
- ,unused
- ,flags[T::value],counters[T::value]
- ,case_insensitive_pass
- );
- }
- // Handle normal attributes
- template <typename T> bool call(T &idx,bool case_insensitive_pass, mpl::true_) const{
- return fusion::at_c<T::value>(elements).parse(
- first
- ,last
- ,context
- ,skipper
- ,fusion::at_c<T::value>(attr)
- ,flags[T::value],counters[T::value]
- ,case_insensitive_pass
- );
- }
-
-
- const Elements &elements;
- Iterator &first;
- const Iterator &last;
- Context & context;
- const Skipper &skipper;
- Flags &flags;
- Counters &counters;
- Attribute &attr;
- bool case_insensitive_pass;
- };
-
- 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 parse_dispatcher<Iterator, Context, Skipper
- , flags_type, counters_type
- , typename traits::wrap_if_not_tuple<Attribute>::type
- > parser_visitor_type;
- parser_visitor_type parse_visitor(elements, first, last
- , context, skipper, flags
- , counters, attr, false);
-
- // 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 parse_dispatcher<Iterator, Context, Skipper
- , flags_type, counters_type
- , typename traits::wrap_if_not_tuple<Attribute>::type
- > parser_visitor_type;
-
- parser_visitor_type parse_visitor(elements,first,last
- ,context,skipper,flags,counters,attr,false);
- parser_visitor_type no_case_parse_visitor(elements,first,last
- ,context,skipper,flags,counters,attr,true);
-
- // 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
-
-/*=============================================================================
- 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/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/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> {};
-
- // 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;
- };
-
- // 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;
- };
-
- // 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;
- }
-
-
- 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
-
-/*=============================================================================
- 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/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/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/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>
-
-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> {};
-
- // 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, mpl::identity, Iterator>::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;
- };
-
- // 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;
- };
-
- // 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, is_same<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;
-
- typedef typename kwd_count::asdfa debug;
-
- // 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;
- }
-
-
- shared_ptr<keywords_type> lookup;
- flags_type & flags;
- };
-
-
-
- // 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 Iterator ,typename Context ,typename Skipper
- ,typename Flags ,typename Counters ,typename Attribute>
- class parse_dispatcher
- : public boost::static_visitor<bool>
- {
- public:
- parse_dispatcher(const Elements &elements,Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Flags &flags, Counters &counters, Attribute& attr, bool case_insensitive_pass) :
- elements(elements), first(first), last(last)
- , context(context), skipper(skipper)
- , flags(flags),counters(counters), attr(attr)
- , case_insensitive_pass(case_insensitive_pass) {}
-
- template<typename T> bool operator()(T& idx) const
- {
- return call(idx,case_insensitive_pass,typename traits::not_is_unused<Attribute>::type());
-
- }
- // Handle unused attributes
- template <typename T> bool call(T &idx, bool case_insensitive_pass, mpl::false_) const{
- return fusion::at_c<T::value>(elements).parse(
- first
- ,last
- ,context
- ,skipper
- ,unused
- ,flags[T::value],counters[T::value]
- ,case_insensitive_pass
- );
- }
- // Handle normal attributes
- template <typename T> bool call(T &idx,bool case_insensitive_pass, mpl::true_) const{
- return fusion::at_c<T::value>(elements).parse(
- first
- ,last
- ,context
- ,skipper
- ,fusion::at_c<T::value>(attr)
- ,flags[T::value],counters[T::value]
- ,case_insensitive_pass
- );
- }
-
-
- const Elements &elements;
- Iterator &first;
- const Iterator &last;
- Context & context;
- const Skipper &skipper;
- Flags &flags;
- Counters &counters;
- Attribute &attr;
- bool case_insensitive_pass;
- };
-
- 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 parse_dispatcher<Iterator, Context, Skipper
- , flags_type, counters_type
- , typename traits::wrap_if_not_tuple<Attribute>::type
- > parser_visitor_type;
- parser_visitor_type parse_visitor(elements, first, last
- , context, skipper, flags
- , counters, attr, false);
-
- // 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 parse_dispatcher<Iterator, Context, Skipper
- , flags_type, counters_type
- , typename traits::wrap_if_not_tuple<Attribute>::type
- > parser_visitor_type;
-
- parser_visitor_type parse_visitor(elements,first,last
- ,context,skipper,flags,counters,attr,false);
- parser_visitor_type no_case_parse_visitor(elements,first,last
- ,context,skipper,flags,counters,attr,true);
-
- // 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
-
-/*=============================================================================
- 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/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/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/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> {};
-
- // 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, mpl::identity, Iterator>::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;
- };
-
- // 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;
- };
-
- // 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;
- }
-
-
- 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
-
-/*=============================================================================
- 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/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/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/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>
-
-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> {};
-
- // 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, mpl::identity, Iterator>::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;
- };
-
- // 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;
- };
-
- // 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, is_same<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;
-
- typedef typename kwd_count::asdfa debug;
-
- // 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;
- }
-
-
- shared_ptr<keywords_type> lookup;
- flags_type & flags;
- };
-
-
-
- // 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 Iterator ,typename Context ,typename Skipper
- ,typename Flags ,typename Counters ,typename Attribute>
- class parse_dispatcher
- : public boost::static_visitor<bool>
- {
- public:
- parse_dispatcher(const Elements &elements,Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Flags &flags, Counters &counters, Attribute& attr, bool case_insensitive_pass) :
- elements(elements), first(first), last(last)
- , context(context), skipper(skipper)
- , flags(flags),counters(counters), attr(attr)
- , case_insensitive_pass(case_insensitive_pass) {}
-
- template<typename T> bool operator()(T& idx) const
- {
- return call(idx,case_insensitive_pass,typename traits::not_is_unused<Attribute>::type());
-
- }
- // Handle unused attributes
- template <typename T> bool call(T &idx, bool case_insensitive_pass, mpl::false_) const{
- return fusion::at_c<T::value>(elements).parse(
- first
- ,last
- ,context
- ,skipper
- ,unused
- ,flags[T::value],counters[T::value]
- ,case_insensitive_pass
- );
- }
- // Handle normal attributes
- template <typename T> bool call(T &idx,bool case_insensitive_pass, mpl::true_) const{
- return fusion::at_c<T::value>(elements).parse(
- first
- ,last
- ,context
- ,skipper
- ,fusion::at_c<T::value>(attr)
- ,flags[T::value],counters[T::value]
- ,case_insensitive_pass
- );
- }
-
-
- const Elements &elements;
- Iterator &first;
- const Iterator &last;
- Context & context;
- const Skipper &skipper;
- Flags &flags;
- Counters &counters;
- Attribute &attr;
- bool case_insensitive_pass;
- };
-
- 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 parse_dispatcher<Iterator, Context, Skipper
- , flags_type, counters_type
- , typename traits::wrap_if_not_tuple<Attribute>::type
- > parser_visitor_type;
- parser_visitor_type parse_visitor(elements, first, last
- , context, skipper, flags
- , counters, attr, false);
-
- // 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 parse_dispatcher<Iterator, Context, Skipper
- , flags_type, counters_type
- , typename traits::wrap_if_not_tuple<Attribute>::type
- > parser_visitor_type;
-
- parser_visitor_type parse_visitor(elements,first,last
- ,context,skipper,flags,counters,attr,false);
- parser_visitor_type no_case_parse_visitor(elements,first,last
- ,context,skipper,flags,counters,attr,true);
-
- // 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
-
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