| /*============================================================================= |
| 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 > > |
| > : mpl::true_ {}; |
| |
| template < typename T> |
| struct use_directive<qi::domain |
| , terminal_ex<repository::tag::ikwd // enables ikwd(key)[p] |
| , fusion::vector1<T > > |
| > : mpl::true_ {}; |
| |
| template < typename T> |
| struct use_directive<qi::domain |
| , terminal_ex<repository::tag::dkwd // enables dkwd(key)[p] |
| , fusion::vector1<T > > |
| > : mpl::true_ {}; |
| |
| template < typename T> |
| struct use_directive<qi::domain |
| , terminal_ex<repository::tag::idkwd // enables idkwd(key)[p] |
| , fusion::vector1<T > > |
| > : mpl::true_ {}; |
| |
| |
| template < typename T1, typename T2> |
| struct use_directive<qi::domain |
| , terminal_ex<repository::tag::kwd // enables kwd(key,exact)[p] |
| , fusion::vector2< T1, T2 > > |
| > : mpl::true_ {}; |
| |
| template < typename T1, typename T2> |
| struct use_directive<qi::domain |
| , terminal_ex<repository::tag::ikwd // enables ikwd(key,exact)[p] |
| , fusion::vector2< T1, T2 > > |
| > : mpl::true_ {}; |
| |
| template < typename T1, typename T2> |
| struct use_directive<qi::domain |
| , terminal_ex<repository::tag::dkwd // enables dkwd(key,exact)[p] |
| , fusion::vector2< T1, T2 > > |
| > : mpl::true_ {}; |
| |
| template < typename T1, typename T2> |
| struct use_directive<qi::domain |
| , terminal_ex<repository::tag::idkwd // enables idkwd(key,exact)[p] |
| , fusion::vector2< T1, T2 > > |
| > : mpl::true_ {}; |
| |
| 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 > > |
| > : mpl::true_ {}; |
| |
| 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 > > |
| > : mpl::true_ {}; |
| |
| template < typename T1, typename T2> |
| struct use_directive<qi::domain |
| , terminal_ex<repository::tag::dkwd // enables dkwd(min, max)[p] |
| , fusion::vector3< T1, T2, T2 > > |
| > : mpl::true_ {}; |
| |
| template < typename T1, typename T2> |
| struct use_directive<qi::domain |
| , terminal_ex<repository::tag::idkwd // enables idkwd(min, max)[p] |
| , fusion::vector3< T1, T2, T2 > > |
| > : mpl::true_ {}; |
| |
| 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 > > |
| > : mpl::true_ {}; |
| |
| 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 > > |
| > : mpl::true_ {}; |
| |
| template < typename T1, typename T2> |
| struct use_directive<qi::domain |
| , terminal_ex<repository::tag::dkwd // enables dkwd(min, inf)[p] |
| , fusion::vector3<T1, T2, inf_type > > |
| > : mpl::true_ {}; |
| |
| template < typename T1, typename T2> |
| struct use_directive<qi::domain |
| , terminal_ex<repository::tag::idkwd // enables idkwd(min, inf)[p] |
| , fusion::vector3<T1, T2, inf_type > > |
| > : mpl::true_ {}; |
| |
| |
| /* 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 repository::dkwd; |
| using repository::idkwd; |
| 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, typename Distinct > |
| struct kwd_parser : spirit::qi::unary_parser<kwd_parser<Subject, KeywordType, LoopIter , NoCase, Distinct > > |
| { |
| struct kwd_parser_id; |
| |
| typedef Subject subject_type; |
| typedef NoCase no_case_keyword; |
| typedef Distinct distinct; |
| |
| 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) {} |
| |
| template<typename CharEncoding> |
| kwd_parser(Subject const& subject |
| , typename add_reference<KeywordType>::type keyword |
| , LoopIter const& iter, CharEncoding encoding) |
| : subject(subject), iter(iter), keyword(keyword,encoding) {} |
| |
| |
| // 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)){ |
| if((!distinct::value) || skipper.parse(first,last,unused,unused,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(distinct::value){ |
| if(no_case_keyword::value) |
| return info("idkwd", subject.what(context)); |
| else |
| return info("dkwd", subject.what(context)); |
| } |
| else |
| { |
| if(no_case_keyword::value) |
| return info("ikwd", subject.what(context)); |
| else |
| return info("kwd", subject.what(context)); |
| } |
| } |
| |
| Subject subject; |
| LoopIter iter; |
| |
| typedef typename mpl::if_< |
| no_case_keyword, |
| spirit::qi::no_case_literal_string< KeywordType, true>, |
| spirit::qi::literal_string<KeywordType, true> >::type keyword_string_type; |
| keyword_string_type 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); |
| } |
| |
| |
| }; |
| |
| template <typename Subject, typename KeywordType, typename LoopIter, typename Distinct> |
| struct complex_kwd_parser : spirit::qi::unary_parser<complex_kwd_parser<Subject, KeywordType, LoopIter, Distinct > > |
| { |
| struct complex_kwd_parser_id; |
| typedef Subject subject_type; |
| typedef Distinct distinct; |
| |
| template <typename Context, typename Iterator> |
| struct attribute |
| { |
| typedef typename |
| traits::build_std_vector< |
| typename traits::attribute_of< |
| Subject, Context, Iterator>::type |
| >::type |
| type; |
| }; |
| |
| |
| complex_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(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)){ |
| if( !distinct::value || skipper.parse(first,last,unused,unused,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(distinct::value) |
| return info("dkwd", subject.what(context)); |
| else |
| return info("kwd", subject.what(context)); |
| } |
| |
| Subject subject; |
| LoopIter iter; |
| |
| KeywordType keyword; |
| private: |
| // silence MSVC warning C4512: assignment operator could not be generated |
| complex_kwd_parser& operator= (complex_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) |
| /////////////////////////////////////////////////////////////////////////// |
| |
| template <typename T1, typename T2, typename Subject, typename Modifiers, typename Distinct, typename MakeDirectiveHelper> |
| struct make_directive_internal_2_args |
| { |
| |
| // is the keyword a string keyword ? |
| typedef typename traits::is_string<T1> is_string_kwd_type; |
| // make the keyword type |
| typedef typename mpl::if_< is_string_kwd_type , |
| T1 , |
| typename result_of::compile<qi::domain, T1>::type |
| >::type keyword_type; |
| |
| typedef typename add_const<keyword_type>::type const_keyword; |
| // select the pass iterator type |
| typedef typename MakeDirectiveHelper::iterator_type iterator_type; |
| // determine if a no case modifier applies to the context |
| typedef has_modifier<Modifiers, tag::char_code_base<tag::no_case> > no_case; |
| // Determine the full type of the kwd / complex_kwd directive |
| typedef typename |
| mpl::if_< |
| is_string_kwd_type, |
| repository::qi::kwd_parser<Subject, const_keyword, iterator_type, no_case, Distinct >, |
| repository::qi::complex_kwd_parser<Subject, const_keyword, iterator_type, Distinct > |
| >::type result_type; |
| |
| // Return a kwd parser object |
| template <typename Terminal> |
| result_type create_kwd_string(Terminal const &term, Subject const & subject, boost::mpl::true_ ) const |
| { |
| typename spirit::detail::get_encoding<Modifiers, |
| spirit::char_encoding::standard>::type encoding; |
| return result_type(subject |
| ,MakeDirectiveHelper::make_iterator(term.args) |
| ,encoding |
| ); |
| } |
| template <typename Terminal> |
| result_type create_kwd_string(Terminal const &term, Subject const & subject, boost::mpl::false_ ) const |
| { |
| return result_type(subject |
| ,fusion::at_c<0>(term.args) |
| ,MakeDirectiveHelper::make_iterator(term.args) |
| ); |
| } |
| template <typename Terminal> |
| result_type create_kwd(Terminal const &term, Subject const & subject, Modifiers const& modifiers, boost::mpl::true_ ) const |
| { |
| return create_kwd_string(term,subject,no_case()); |
| } |
| // Return a complex_kwd parser object |
| template <typename Terminal> |
| result_type create_kwd(Terminal const &term , Subject const & subject, Modifiers const& modifiers, boost::mpl::false_ ) const |
| { |
| return result_type(subject |
| ,compile<qi::domain>(fusion::at_c<0>(term.args),modifiers) |
| ,MakeDirectiveHelper::make_iterator(term.args) |
| ); |
| } |
| // Select which object type to return |
| template <typename Terminal> |
| result_type operator()( |
| Terminal const& term, Subject const& subject, Modifiers const& modifiers) const |
| { |
| return create_kwd(term, subject, modifiers, is_string_kwd_type()); |
| } |
| |
| }; |
| |
| // Directive kwd(key)[p] |
| template <typename T1, typename Subject, typename Modifiers, typename Distinct> |
| struct make_directive_internal |
| { |
| // is the keyword a string keyword ? |
| typedef typename traits::is_string<T1> is_string_kwd_type; |
| // make the keyword type |
| typedef typename mpl::if_< is_string_kwd_type , |
| T1 , |
| typename result_of::compile<qi::domain, T1, Modifiers>::type |
| >::type keyword_type; |
| |
| typedef typename add_const<keyword_type>::type const_keyword; |
| // select the pass iterator type |
| typedef repository::qi::kwd_pass_iterator<int> iterator_type; |
| // determine if a no case modifier applies to the context |
| typedef has_modifier<Modifiers, tag::char_code_base<tag::no_case> > no_case; |
| // Determine the full type of the kwd / complex_kwd directive |
| typedef typename |
| mpl::if_< |
| is_string_kwd_type, |
| repository::qi::kwd_parser<Subject, const_keyword, iterator_type, no_case, Distinct >, |
| repository::qi::complex_kwd_parser<Subject, const_keyword, iterator_type, Distinct> |
| >::type result_type; |
| |
| // Return a kwd parser object |
| template <typename Terminal> |
| result_type create_kwd_string(Terminal const &term, Subject const & subject, boost::mpl::true_) 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() |
| ,encoding |
| ); |
| |
| } |
| template <typename Terminal> |
| result_type create_kwd_string(Terminal const &term, Subject const & subject, boost::mpl::false_) const |
| { |
| return result_type(subject |
| ,fusion::at_c<0>(term.args) |
| ,iterator_type() |
| ); |
| } |
| template <typename Terminal> |
| result_type create_kwd(Terminal const &term, Subject const & subject, Modifiers const& modifiers, boost::mpl::true_ ) const |
| { |
| return create_kwd_string(term,subject,no_case()); |
| } |
| // Return a complex_kwd parser object |
| template <typename Terminal> |
| result_type create_kwd(Terminal const &term , Subject const & subject, Modifiers const& modifiers, boost::mpl::false_ ) const |
| { |
| return result_type(subject |
| ,compile<qi::domain>(fusion::at_c<0>(term.args),modifiers) |
| ,iterator_type() |
| ); |
| } |
| // Select which object type to return |
| template <typename Terminal> |
| result_type operator()( |
| Terminal const& term, Subject const& subject, Modifiers const& modifiers ) const |
| { |
| return create_kwd(term, subject, modifiers, is_string_kwd_type()); |
| } |
| }; |
| |
| template <typename T1, typename Subject, typename Modifiers> |
| struct make_directive< |
| terminal_ex<repository::tag::kwd, fusion::vector1<T1> >, Subject, Modifiers> |
| { |
| typedef make_directive_internal<T1, Subject, Modifiers, mpl::false_> make_directive_type; |
| typedef typename make_directive_type::result_type result_type; |
| template <typename Terminal> |
| result_type operator()( |
| Terminal const& term, Subject const& subject, Modifiers const& modifiers) const |
| { |
| |
| return make_directive_type()(term, subject, modifiers); |
| } |
| |
| }; |
| |
| template <typename T1, typename Subject, typename Modifiers> |
| struct make_directive< |
| terminal_ex<repository::tag::dkwd, fusion::vector1<T1> >, Subject, Modifiers> |
| { |
| typedef make_directive_internal<T1, Subject, Modifiers, mpl::true_> make_directive_type; |
| typedef typename make_directive_type::result_type result_type; |
| template <typename Terminal> |
| result_type operator()( |
| Terminal const& term, Subject const& subject, Modifiers const& modifiers) const |
| { |
| |
| return make_directive_type()(term, subject, modifiers); |
| } |
| |
| }; |
| |
| |
| |
| // 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_, mpl::false_ > 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() |
| ,encoding |
| ); |
| } |
| }; |
| |
| template <typename T1, typename Subject, typename Modifiers> |
| struct make_directive< |
| terminal_ex<repository::tag::idkwd, 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_, 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() |
| ,encoding |
| ); |
| } |
| }; |
| |
| // Directive kwd(key,exact)[p] |
| template <typename T> |
| struct make_exact_helper |
| { |
| typedef repository::qi::kwd_exact_iterator<T> iterator_type; |
| template<typename Args> |
| static iterator_type make_iterator(Args const& args) |
| { |
| return iterator_type(fusion::at_c<1>(args)); |
| } |
| }; |
| |
| template <typename T1, typename T2, typename Subject, typename Modifiers> |
| struct make_directive< |
| terminal_ex<repository::tag::kwd, fusion::vector2<T1,T2> >, Subject, Modifiers> |
| { |
| typedef make_directive_internal_2_args< T1 |
| , T2 |
| , Subject |
| , Modifiers |
| , mpl::false_ |
| , make_exact_helper<T2> |
| > make_directive_type; |
| typedef typename make_directive_type::result_type result_type; |
| template <typename Terminal> |
| result_type operator()( |
| Terminal const& term, Subject const& subject, Modifiers const& modifiers) const |
| { |
| |
| return make_directive_type()(term,subject, modifiers); |
| } |
| |
| }; |
| |
| template <typename T1, typename T2, typename Subject, typename Modifiers> |
| struct make_directive< |
| terminal_ex<repository::tag::dkwd, fusion::vector2<T1,T2> >, Subject, Modifiers> |
| { |
| typedef make_directive_internal_2_args< T1 |
| , T2 |
| , Subject |
| , Modifiers |
| , mpl::true_ |
| , make_exact_helper<T2> |
| > make_directive_type; |
| |
| typedef typename make_directive_type::result_type result_type; |
| template <typename Terminal> |
| result_type operator()( |
| Terminal const& term, Subject const& subject, Modifiers const& modifiers) const |
| { |
| |
| return make_directive_type()(term, subject, modifiers); |
| } |
| |
| }; |
| |
| |
| // 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_, mpl::false_ > result_type; |
| |
| template <typename Terminal> |
| result_type operator()( |
| Terminal const& term, Subject const& subject, Modifiers const& modifiers) 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) |
| , encoding |
| ); |
| } |
| }; |
| |
| template <typename T1, typename T2, typename Subject, typename Modifiers> |
| struct make_directive< |
| terminal_ex<repository::tag::idkwd, 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_, mpl::true_ > result_type; |
| |
| template <typename Terminal> |
| result_type operator()( |
| Terminal const& term, Subject const& subject, Modifiers const& modifiers) 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) |
| , encoding |
| ); |
| } |
| }; |
| |
| |
| // Directive kwd(min, max)[p] |
| |
| template <typename T> |
| struct make_finite_helper |
| { |
| typedef repository::qi::kwd_finite_iterator<T> iterator_type; |
| template<typename Args> |
| static iterator_type make_iterator(Args const& args) |
| { |
| return iterator_type(fusion::at_c<1>(args),fusion::at_c<2>(args)); |
| } |
| |
| }; |
| |
| 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 make_directive_internal_2_args< T1 |
| , T2 |
| , Subject |
| , Modifiers |
| , mpl::false_ |
| , make_finite_helper<T2> |
| > make_directive_type; |
| |
| |
| typedef typename make_directive_type::result_type result_type; |
| template <typename Terminal> |
| result_type operator()( |
| Terminal const& term, Subject const& subject, Modifiers const& modifiers) const |
| { |
| |
| return make_directive_type()(term,subject, modifiers); |
| } |
| |
| }; |
| |
| template <typename T1, typename T2, typename Subject, typename Modifiers> |
| struct make_directive< |
| terminal_ex<repository::tag::dkwd, fusion::vector3<T1,T2,T2> >, Subject, Modifiers> |
| { |
| |
| typedef make_directive_internal_2_args< T1 |
| , T2 |
| , Subject |
| , Modifiers |
| , mpl::true_ |
| , make_finite_helper<T2> |
| > make_directive_type; |
| |
| typedef typename make_directive_type::result_type result_type; |
| template <typename Terminal> |
| result_type operator()( |
| Terminal const& term, Subject const& subject, Modifiers const& modifiers) const |
| { |
| |
| return make_directive_type()(term,subject, modifiers); |
| } |
| |
| }; |
| |
| // 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_, mpl::false_ > 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( |
| fusion::at_c<1>(term.args) |
| , fusion::at_c<2>(term.args) |
| , encoding |
| ) |
| ); |
| } |
| }; |
| |
| template <typename T1, typename T2, typename Subject, typename Modifiers> |
| struct make_directive< |
| terminal_ex<repository::tag::idkwd, 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_, 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( |
| fusion::at_c<1>(term.args) |
| , fusion::at_c<2>(term.args) |
| , encoding |
| ) |
| ); |
| } |
| }; |
| |
| |
| // Directive kwd(min, inf)[p] |
| |
| template <typename T> |
| struct make_infinite_helper |
| { |
| typedef repository::qi::kwd_infinite_iterator<T> iterator_type; |
| template<typename Args> |
| static iterator_type make_iterator(Args const& args) |
| { |
| return iterator_type(fusion::at_c<1>(args)); |
| } |
| |
| }; |
| |
| |
| 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 make_directive_internal_2_args< T1 |
| , T2 |
| , Subject |
| , Modifiers |
| , mpl::false_ |
| , make_infinite_helper<T2> |
| > make_directive_type; |
| |
| typedef typename make_directive_type::result_type result_type; |
| template <typename Terminal> |
| result_type operator()( |
| Terminal const& term, Subject const& subject, unused_type) const |
| { |
| |
| return make_directive_type()(term,subject, unused_type()); |
| } |
| |
| }; |
| |
| template <typename T1, typename T2, typename Subject, typename Modifiers> |
| struct make_directive< |
| terminal_ex<repository::tag::dkwd, fusion::vector3<T1,T2,inf_type> >, Subject, Modifiers> |
| { |
| typedef make_directive_internal_2_args< T1 |
| , T2 |
| , Subject |
| , Modifiers |
| , mpl::false_ |
| , make_infinite_helper<T2> |
| > make_directive_type; |
| |
| typedef typename make_directive_type::result_type result_type; |
| template <typename Terminal> |
| result_type operator()( |
| Terminal const& term, Subject const& subject, unused_type) const |
| { |
| |
| return make_directive_type()(term,subject, unused_type()); |
| } |
| |
| }; |
| |
| |
| // 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_, mpl::false_ > 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) |
| , encoding |
| ); |
| } |
| }; |
| |
| template <typename T1, typename T2, typename Subject, typename Modifiers> |
| struct make_directive< |
| terminal_ex<repository::tag::idkwd |
| , 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_, 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) |
| , encoding |
| ); |
| } |
| }; |
| |
| |
| }}} |
| |
| namespace boost { namespace spirit { namespace traits |
| { |
| template <typename Subject, typename KeywordType |
| , typename LoopIter, typename NoCase , typename Distinct> |
| struct has_semantic_action< |
| repository::qi::kwd_parser< Subject, KeywordType, LoopIter, NoCase, Distinct > > |
| : unary_has_semantic_action<Subject> {}; |
| |
| template <typename Subject, typename KeywordType |
| , typename LoopIter, typename Distinct > |
| struct has_semantic_action< |
| repository::qi::complex_kwd_parser< Subject, KeywordType, LoopIter, Distinct > > |
| : unary_has_semantic_action<Subject> {}; |
| |
| template <typename Subject, typename KeywordType |
| , typename LoopIter, typename NoCase, typename Attribute, typename Context |
| , typename Iterator, typename Distinct> |
| struct handles_container<repository::qi::kwd_parser<Subject, KeywordType, LoopIter, NoCase, Distinct>, Attribute |
| , Context, Iterator> |
| : unary_handles_container<Subject, Attribute, Context, Iterator> {}; |
| |
| template <typename Subject, typename KeywordType |
| , typename LoopIter |
| , typename Attribute, typename Context |
| , typename Iterator, typename Distinct> |
| struct handles_container<repository::qi::complex_kwd_parser<Subject, KeywordType, LoopIter, Distinct>, Attribute |
| , Context, Iterator> |
| : unary_handles_container<Subject, Attribute, Context, Iterator> {}; |
| |
| }}} |
| |
| #endif |
| |