/Src/Dependencies/Boost/boost/spirit/repository/home/qi/directive/kwd.hpp
http://hadesmem.googlecode.com/ · C++ Header · 588 lines · 442 code · 92 blank · 54 comment · 16 complexity · 2aa45a506ae27c86dba12e802026334d MD5 · raw file
- /*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
- Copyright (c) 2011 Thomas Bernard
- Distributed under the Boost Software License, Version 1.0. (See accompanying
- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
- =============================================================================*/
- #if !defined(SPIRIT_KWD_NOVEMBER_14_2008_1148AM)
- #define SPIRIT_KWD_NOVEMBER_14_2008_1148AM
- #if defined(_MSC_VER)
- #pragma once
- #endif
- #include <boost/spirit/home/qi/meta_compiler.hpp>
- #include <boost/spirit/home/qi/parser.hpp>
- #include <boost/spirit/home/qi/auxiliary/lazy.hpp>
- #include <boost/spirit/home/qi/operator/kleene.hpp>
- #include <boost/spirit/home/support/container.hpp>
- #include <boost/spirit/home/qi/detail/attributes.hpp>
- #include <boost/spirit/home/qi/detail/fail_function.hpp>
- #include <boost/spirit/home/support/info.hpp>
- #include <boost/spirit/repository/home/support/kwd.hpp>
- #include <boost/fusion/include/at.hpp>
- #include <boost/foreach.hpp>
- #include <vector>
- namespace boost { namespace spirit
- {
- ///////////////////////////////////////////////////////////////////////////
- // Enablers
- ///////////////////////////////////////////////////////////////////////////
-
- template < typename T>
- struct use_directive<qi::domain
- , terminal_ex<repository::tag::kwd // enables kwd(key)[p]
- , fusion::vector1<T > >
- > : traits::is_string<T> {};
-
- template < typename T>
- struct use_directive<qi::domain
- , terminal_ex<repository::tag::ikwd // enables ikwd(key)[p]
- , fusion::vector1<T > >
- > : traits::is_string<T> {};
-
-
- template < typename T1, typename T2>
- struct use_directive<qi::domain
- , terminal_ex<repository::tag::kwd // enables kwd(key,exact)[p]
- , fusion::vector2< T1, T2 > >
- > : traits::is_string<T1> {};
- template < typename T1, typename T2>
- struct use_directive<qi::domain
- , terminal_ex<repository::tag::ikwd // enables ikwd(key,exact)[p]
- , fusion::vector2< T1, T2 > >
- > : traits::is_string<T1> {};
- template < typename T1, typename T2>
- struct use_directive<qi::domain
- , terminal_ex<repository::tag::kwd // enables kwd(min, max)[p]
- , fusion::vector3< T1, T2, T2 > >
- > : traits::is_string<T1> {};
- template < typename T1, typename T2>
- struct use_directive<qi::domain
- , terminal_ex<repository::tag::ikwd // enables ikwd(min, max)[p]
- , fusion::vector3< T1, T2, T2 > >
- > : traits::is_string<T1> {};
- template < typename T1, typename T2>
- struct use_directive<qi::domain
- , terminal_ex<repository::tag::kwd // enables kwd(min, inf)[p]
- , fusion::vector3<T1, T2, inf_type > >
- > : traits::is_string<T1> {};
-
- template < typename T1, typename T2>
- struct use_directive<qi::domain
- , terminal_ex<repository::tag::ikwd // enables ikwd(min, inf)[p]
- , fusion::vector3<T1, T2, inf_type > >
- > : traits::is_string<T1> {};
- /* template <> // enables *lazy* kwd(exact)[p]
- struct use_lazy_directive<
- qi::domain
- , tag::kwd
- , 1 // arity
- > : mpl::true_ {};
- template <> // enables *lazy* kwd(min, max)[p]
- struct use_lazy_directive< // and kwd(min, inf)[p]
- qi::domain
- , tag::kwd
- , 2 // arity
- > : mpl::true_ {};
- */
- }}
- namespace boost { namespace spirit { namespace repository { namespace qi
- {
- using repository::kwd;
- using repository::ikwd;
- using spirit::inf;
- using spirit::inf_type;
- template <typename T>
- struct kwd_pass_iterator // handles kwd(exact)[p]
- {
- kwd_pass_iterator() {}
- bool flag_init() const { return true; }
- bool register_successful_parse(bool &flag,T &i) const {
- flag=true;
- return true;
- }
-
- private:
- // silence MSVC warning C4512: assignment operator could not be generated
- kwd_pass_iterator& operator= (kwd_pass_iterator const&);
- };
- template <typename T>
- struct kwd_exact_iterator // handles kwd(exact)[p]
- {
- kwd_exact_iterator(T const exact)
- : exact(exact){}
- typedef T type;
- bool flag_init() const { return false; }
- bool register_successful_parse(bool &flag,T &i) const {
- i++;
- if(i<exact)
- {
- flag=false;
- return true;
- }
- else if(i==exact)
- {
- flag=true;
- return true;
- }
- else
- return flag=false;
-
- }
- T const exact;
- private:
- // silence MSVC warning C4512: assignment operator could not be generated
- kwd_exact_iterator& operator= (kwd_exact_iterator const&);
- };
- template <typename T>
- struct kwd_finite_iterator // handles kwd(min, max)[p]
- {
- kwd_finite_iterator(T const min, T const max)
- : min BOOST_PREVENT_MACRO_SUBSTITUTION (min)
- , max BOOST_PREVENT_MACRO_SUBSTITUTION (max)
- {}
- typedef T type;
- bool flag_init() const { return min==0; }
- bool register_successful_parse(bool &flag,T &i) const {
- i++;
- if(i<min)
- {
- flag=false;
- return true;
- }
- else if(i>=min && i<=max)
- {
- return flag=true;
- }
- else
- return flag=false;
- }
- T const min;
- T const max;
- private:
- // silence MSVC warning C4512: assignment operator could not be generated
- kwd_finite_iterator& operator= (kwd_finite_iterator const&);
- };
- template <typename T>
- struct kwd_infinite_iterator // handles kwd(min, inf)[p]
- {
- kwd_infinite_iterator(T const min)
- : min BOOST_PREVENT_MACRO_SUBSTITUTION (min) {}
- typedef T type;
- bool flag_init() const { return min==0; }
- bool register_successful_parse(bool &flag,T &i) const {
- i++;
- flag = i>=min;
- return true;
- }
- T const min;
- private:
- // silence MSVC warning C4512: assignment operator could not be generated
- kwd_infinite_iterator& operator= (kwd_infinite_iterator const&);
- };
- // This class enables the transportation of parameters needed to call
- // the occurence constraint checker from higher level calls
- // It also serves to select the correct parse function call
- // of the keyword parser. The implementation changes depending if it is
- // called form a keyword parsing loop or not.
- template <typename Skipper, typename NoCasePass>
- struct skipper_keyword_marker
- {
- typedef NoCasePass no_case_pass;
-
- skipper_keyword_marker(Skipper const &skipper,bool &flag,int &counter) :
- skipper(skipper)
- , flag(flag)
- , counter(counter)
- {}
-
- const Skipper &skipper;
- bool &flag;
- int &counter;
- };
-
- template <typename Subject, typename KeywordType, typename LoopIter , typename NoCase >
- struct kwd_parser : spirit::qi::unary_parser<kwd_parser<Subject, KeywordType, LoopIter , NoCase > >
- {
- struct kwd_parser_id;
-
- typedef Subject subject_type;
- typedef NoCase no_case_keyword;
-
- typedef typename
- remove_const<typename traits::char_type_of<KeywordType>::type>::type
- char_type;
-
- typedef std::basic_string<char_type> keyword_type;
-
- template <typename Context, typename Iterator>
- struct attribute
- {
- typedef typename
- traits::build_std_vector<
- typename traits::attribute_of<
- Subject, Context, Iterator>::type
- >::type
- type;
- };
-
- kwd_parser(Subject const& subject
- , typename add_reference<KeywordType>::type keyword
- , LoopIter const& iter)
- : subject(subject), iter(iter), keyword(keyword) {}
-
- // Call the subject parser on a non container attribute
- template <typename Iterator, typename Context
- , typename Skipper, typename Attribute>
- bool parse_impl(Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Attribute& attr,mpl::false_) const
- {
- return subject.parse(first,last,context,skipper,attr);
- }
-
- // Call the subject parser on a container attribute
- template <typename Iterator, typename Context
- , typename Skipper, typename Attribute>
- bool parse_impl(Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Attribute& attr,mpl::true_) const
- {
-
- // synthesized attribute needs to be default constructed
- typename traits::container_value<Attribute>::type val =
- typename traits::container_value<Attribute>::type();
- Iterator save = first;
- bool r = subject.parse(first,last,context,skipper, val);
- if (r)
- {
- // push the parsed value into our attribute
- r = traits::push_back(attr, val);
- if (!r)
- first = save;
- }
- return r;
- }
-
- template <typename Iterator, typename Context
- , typename Skipper, typename Attribute,typename NoCasePass>
- bool parse(Iterator& first, Iterator const& last
- , Context& context, skipper_keyword_marker<Skipper,NoCasePass> const& skipper
- , Attribute &attr) const
- {
-
- typedef typename traits::attribute_of<
- Subject, Context, Iterator>::type
- subject_attribute;
-
- typedef typename mpl::and_<
- traits::is_container<Attribute>
- , mpl::not_< traits::is_weak_substitute< subject_attribute,Attribute > >
- >::type predicate;
-
- if((no_case_keyword::value && NoCasePass::value) || !NoCasePass::value)
- {
- if(parse_impl(first,last,context,skipper.skipper,attr, predicate()))
- return iter.register_successful_parse(skipper.flag,skipper.counter);
- }
- return false;
- }
-
- template <typename Iterator, typename Context
- , typename Skipper, typename Attribute>
- bool parse(Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Attribute& attr) const
- {
- typedef typename traits::attribute_of<
- Subject, Context, Iterator>::type
- subject_attribute;
-
- typedef typename mpl::and_<
- traits::is_container<Attribute>
- , mpl::not_< traits::is_weak_substitute< subject_attribute,Attribute > >
- >::type predicate;
-
- // Parse the keyword
- bool flag = iter.flag_init();
- int counter = 0;
- Iterator save = first;
- spirit::qi::skip_over(first, last, skipper);
- if(keyword.parse(first,last,context,skipper,unused)){
- // Followed by the subject parser
- spirit::qi::skip_over(first, last, skipper);
- if(parse_impl(first,last,context,skipper,attr, predicate()))
- {
- return iter.register_successful_parse(flag,counter);
- }
- }
- first = save;
- return flag;
- }
-
-
- template <typename Context>
- info what(Context& context) const
- {
- if(no_case_keyword::value)
- return info("ikwd", subject.what(context));
- else
- return info("kwd", subject.what(context));
- }
- Subject subject;
- LoopIter iter;
-
- spirit::qi::literal_string<KeywordType, true> keyword;
- private:
- // silence MSVC warning C4512: assignment operator could not be generated
- kwd_parser& operator= (kwd_parser const&);
- template <typename Iterator, typename Context, typename Skipper>
- static spirit::qi::detail::fail_function<Iterator, Context, Skipper>
- fail_function(
- Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper)
- {
- return spirit::qi::detail::fail_function<Iterator, Context, Skipper>
- (first, last, context, skipper);
- }
- };
- }}}}
- ///////////////////////////////////////////////////////////////////////////////
- namespace boost { namespace spirit { namespace qi
- {
- ///////////////////////////////////////////////////////////////////////////
- // Parser generators: make_xxx function (objects)
- ///////////////////////////////////////////////////////////////////////////
-
- // Directive kwd(key)[p]
- template <typename T1, typename Subject, typename Modifiers>
- struct make_directive<
- terminal_ex<repository::tag::kwd, fusion::vector1<T1> >, Subject, Modifiers>
- {
- typedef typename add_const<T1>::type const_keyword;
- typedef repository::qi::kwd_pass_iterator<int> iterator_type;
- typedef has_modifier<Modifiers, tag::char_code_base<tag::no_case> > no_case;
-
-
- typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, no_case > result_type;
- template <typename Terminal>
- result_type operator()(
- Terminal const& term, Subject const& subject, unused_type) const
- {
- return result_type(subject
- ,fusion::at_c<0>(term.args)
- ,iterator_type()
- );
- }
- };
-
- // Directive ikwd(key)[p]
- template <typename T1, typename Subject, typename Modifiers>
- struct make_directive<
- terminal_ex<repository::tag::ikwd, fusion::vector1<T1> >, Subject, Modifiers>
- {
- typedef typename add_const<T1>::type const_keyword;
- typedef repository::qi::kwd_pass_iterator<int> iterator_type;
-
- typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_ > result_type;
- template <typename Terminal>
- result_type operator()(
- Terminal const& term, Subject const& subject, unused_type) const
- {
- /* typename spirit::detail::get_encoding<Modifiers,
- spirit::char_encoding::standard>::type encoding;*/
-
- return result_type(subject
- ,fusion::at_c<0>(term.args)
- ,iterator_type()
- );
- }
- };
-
- // Directive kwd(key,exact)[p]
- template <typename T1, typename T2, typename Subject, typename Modifiers>
- struct make_directive<
- terminal_ex<repository::tag::kwd, fusion::vector2<T1,T2> >, Subject, Modifiers>
- {
- typedef typename add_const<T1>::type const_keyword;
- typedef repository::qi::kwd_exact_iterator<T2> iterator_type;
- typedef has_modifier<Modifiers, tag::char_code_base<tag::no_case> > no_case;
-
- typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, no_case > result_type;
- template <typename Terminal>
- result_type operator()(
- Terminal const& term, Subject const& subject, unused_type) const
- {
- return result_type(subject
- ,fusion::at_c<0>(term.args)
- ,fusion::at_c<1>(term.args)
- );
- }
- };
- // Directive ikwd(key,exact)[p]
- template <typename T1, typename T2, typename Subject, typename Modifiers>
- struct make_directive<
- terminal_ex<repository::tag::ikwd, fusion::vector2<T1,T2> >, Subject, Modifiers>
- {
- typedef typename add_const<T1>::type const_keyword;
- typedef repository::qi::kwd_exact_iterator<T2> iterator_type;
-
- typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_ > result_type;
-
- template <typename Terminal>
- result_type operator()(
- Terminal const& term, Subject const& subject, unused_type) const
- {
- return result_type(subject
- , fusion::at_c<0>(term.args)
- , fusion::at_c<1>(term.args)
- );
- }
- };
-
- // Directive kwd(min, max)[p]
- template <typename T1, typename T2, typename Subject, typename Modifiers>
- struct make_directive<
- terminal_ex<repository::tag::kwd, fusion::vector3< T1, T2, T2> >, Subject, Modifiers>
- {
- typedef typename add_const<T1>::type const_keyword;
- typedef repository::qi::kwd_finite_iterator<T2> iterator_type;
- typedef has_modifier<Modifiers, tag::char_code_base<tag::no_case> > no_case;
-
- typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, no_case > result_type;
- template <typename Terminal>
- result_type operator()(
- Terminal const& term, Subject const& subject, unused_type) const
- {
- return result_type(subject, fusion::at_c<0>(term.args),
- iterator_type(
- fusion::at_c<1>(term.args)
- , fusion::at_c<2>(term.args)
- )
- );
- }
- };
- // Directive ikwd(min, max)[p]
- template <typename T1, typename T2, typename Subject, typename Modifiers>
- struct make_directive<
- terminal_ex<repository::tag::ikwd, fusion::vector3< T1, T2, T2> >, Subject, Modifiers>
- {
- typedef typename add_const<T1>::type const_keyword;
- typedef repository::qi::kwd_finite_iterator<T2> iterator_type;
-
- typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_ > result_type;
- template <typename Terminal>
- result_type operator()(
- Terminal const& term, Subject const& subject, unused_type) const
- {
-
- return result_type(subject, fusion::at_c<0>(term.args),
- iterator_type(
- fusion::at_c<1>(term.args)
- , fusion::at_c<2>(term.args)
- )
- );
- }
- };
-
- // Directive kwd(min, inf)[p]
- template <typename T1, typename T2, typename Subject, typename Modifiers>
- struct make_directive<
- terminal_ex<repository::tag::kwd
- , fusion::vector3<T1, T2, inf_type> >, Subject, Modifiers>
- {
- typedef typename add_const<T1>::type const_keyword;
- typedef repository::qi::kwd_infinite_iterator<T2> iterator_type;
- typedef has_modifier<Modifiers, tag::char_code_base<tag::no_case> > no_case;
-
- typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, no_case > result_type;
- template <typename Terminal>
- result_type operator()(
- Terminal const& term, Subject const& subject, unused_type) const
- {
- return result_type(subject
- , fusion::at_c<0>(term.args)
- , fusion::at_c<1>(term.args)
- );
- }
- };
-
- // Directive ikwd(min, inf)[p]
- template <typename T1, typename T2, typename Subject, typename Modifiers>
- struct make_directive<
- terminal_ex<repository::tag::ikwd
- , fusion::vector3<T1, T2, inf_type> >, Subject, Modifiers>
- {
- typedef typename add_const<T1>::type const_keyword;
- typedef repository::qi::kwd_infinite_iterator<T2> iterator_type;
-
- typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_ > result_type;
- template <typename Terminal>
- result_type operator()(
- Terminal const& term, Subject const& subject, unused_type) const
- {
- typename spirit::detail::get_encoding<Modifiers,
- spirit::char_encoding::standard>::type encoding;
-
- return result_type(subject
- , fusion::at_c<0>(term.args)
- , fusion::at_c<1>(term.args)
- );
- }
- };
-
-
- }}}
- namespace boost { namespace spirit { namespace traits
- {
- template <typename Subject, typename KeywordType
- , typename LoopIter, typename NoCase >
- struct has_semantic_action<
- repository::qi::kwd_parser< Subject, KeywordType, LoopIter, NoCase > >
- : unary_has_semantic_action<Subject> {};
- }}}
- #endif