Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-19 09:47:44

0001 /*=============================================================================
0002     Copyright (c) 2001-2011 Joel de Guzman
0003     Copyright (c) 2001-2011 Hartmut Kaiser
0004 
0005     Distributed under the Boost Software License, Version 1.0. (See accompanying
0006     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0007 =============================================================================*/
0008 #ifndef BOOST_SPIRIT_QI_DIRECTIVE_REPEAT_HPP
0009 #define BOOST_SPIRIT_QI_DIRECTIVE_REPEAT_HPP
0010 
0011 #if defined(_MSC_VER)
0012 #pragma once
0013 #endif
0014 
0015 #include <boost/spirit/home/qi/meta_compiler.hpp>
0016 #include <boost/spirit/home/qi/parser.hpp>
0017 #include <boost/spirit/home/qi/auxiliary/lazy.hpp>
0018 #include <boost/spirit/home/qi/operator/kleene.hpp>
0019 #include <boost/spirit/home/support/container.hpp>
0020 #include <boost/spirit/home/support/common_terminals.hpp>
0021 #include <boost/spirit/home/qi/detail/attributes.hpp>
0022 #include <boost/spirit/home/qi/detail/fail_function.hpp>
0023 #include <boost/spirit/home/qi/detail/pass_container.hpp>
0024 #include <boost/spirit/home/support/info.hpp>
0025 #include <boost/spirit/home/support/has_semantic_action.hpp>
0026 #include <boost/spirit/home/support/handles_container.hpp>
0027 #include <boost/fusion/include/at.hpp>
0028 #include <vector>
0029 
0030 namespace boost { namespace spirit
0031 {
0032     ///////////////////////////////////////////////////////////////////////////
0033     // Enablers
0034     ///////////////////////////////////////////////////////////////////////////
0035     template <>
0036     struct use_directive<qi::domain, tag::repeat>   // enables repeat[p]
0037       : mpl::true_ {};
0038 
0039     template <typename T>
0040     struct use_directive<qi::domain
0041       , terminal_ex<tag::repeat                     // enables repeat(exact)[p]
0042         , fusion::vector1<T> >
0043     > : mpl::true_ {};
0044 
0045     template <typename T>
0046     struct use_directive<qi::domain
0047       , terminal_ex<tag::repeat                     // enables repeat(min, max)[p]
0048         , fusion::vector2<T, T> >
0049     > : mpl::true_ {};
0050 
0051     template <typename T>
0052     struct use_directive<qi::domain
0053       , terminal_ex<tag::repeat                     // enables repeat(min, inf)[p]
0054         , fusion::vector2<T, inf_type> >
0055     > : mpl::true_ {};
0056 
0057     template <>                                     // enables *lazy* repeat(exact)[p]
0058     struct use_lazy_directive<
0059         qi::domain
0060       , tag::repeat
0061       , 1 // arity
0062     > : mpl::true_ {};
0063 
0064     template <>                                     // enables *lazy* repeat(min, max)[p]
0065     struct use_lazy_directive<                      // and repeat(min, inf)[p]
0066         qi::domain
0067       , tag::repeat
0068       , 2 // arity
0069     > : mpl::true_ {};
0070 }}
0071 
0072 namespace boost { namespace spirit { namespace qi
0073 {
0074 #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
0075     using spirit::repeat;
0076     using spirit::inf;
0077 #endif
0078     using spirit::repeat_type;
0079     using spirit::inf_type;
0080 
0081 #ifdef _MSC_VER
0082 #  pragma warning(push)
0083 #  pragma warning(disable: 4512) // assignment operator could not be generated.
0084 #endif
0085     template <typename T>
0086     struct exact_iterator // handles repeat(exact)[p]
0087     {
0088         exact_iterator(T const exact_)
0089           : exact(exact_) {}
0090 
0091         typedef T type;
0092         T start() const { return 0; }
0093         bool got_max(T i) const { return i >= exact; }
0094         bool got_min(T i) const { return i >= exact; }
0095 
0096         T const exact;
0097     };
0098 
0099     template <typename T>
0100     struct finite_iterator // handles repeat(min, max)[p]
0101     {
0102         finite_iterator(T const min_, T const max_)
0103           : min BOOST_PREVENT_MACRO_SUBSTITUTION (min_)
0104           , max BOOST_PREVENT_MACRO_SUBSTITUTION (max_) {}
0105 
0106         typedef T type;
0107         T start() const { return 0; }
0108         bool got_max(T i) const { return i >= max; }
0109         bool got_min(T i) const { return i >= min; }
0110 
0111         T const min;
0112         T const max;
0113     };
0114 
0115     template <typename T>
0116     struct infinite_iterator // handles repeat(min, inf)[p]
0117     {
0118         infinite_iterator(T const min_)
0119           : min BOOST_PREVENT_MACRO_SUBSTITUTION (min_) {}
0120 
0121         typedef T type;
0122         T start() const { return 0; }
0123         bool got_max(T /*i*/) const { return false; }
0124         bool got_min(T i) const { return i >= min; }
0125 
0126         T const min;
0127     };
0128 #ifdef _MSC_VER
0129 #  pragma warning(pop)
0130 #endif
0131 
0132     template <typename Subject, typename LoopIter>
0133     struct repeat_parser : unary_parser<repeat_parser<Subject, LoopIter> >
0134     {
0135         typedef Subject subject_type;
0136 
0137         template <typename Context, typename Iterator>
0138         struct attribute
0139         {
0140             // Build a std::vector from the subject's attribute. Note
0141             // that build_std_vector may return unused_type if the
0142             // subject's attribute is an unused_type.
0143             typedef typename
0144                 traits::build_std_vector<
0145                     typename traits::attribute_of<
0146                         Subject, Context, Iterator>::type
0147                 >::type
0148             type;
0149         };
0150 
0151         repeat_parser(Subject const& subject_, LoopIter const& iter_)
0152           : subject(subject_), iter(iter_) {}
0153 
0154         template <typename F>
0155         bool parse_container(F f) const
0156         {
0157             typename LoopIter::type i = iter.start();
0158             for (/**/; !iter.got_min(i); ++i)
0159             {
0160                 if (f (subject))
0161                     return false;
0162             }
0163 
0164             // parse some more up to the maximum specified
0165             typename F::iterator_type save = f.f.first;
0166             for (/**/; !iter.got_max(i); ++i)
0167             {
0168                 if (f (subject))
0169                     break;
0170                 save = f.f.first;
0171             }
0172 
0173             f.f.first = save;
0174             return true;
0175         }
0176 
0177         template <typename Iterator, typename Context
0178           , typename Skipper, typename Attribute>
0179         bool parse(Iterator& first, Iterator const& last
0180           , Context& context, Skipper const& skipper
0181           , Attribute& attr_) const
0182         {
0183             typedef detail::fail_function<Iterator, Context, Skipper>
0184                 fail_function;
0185 
0186             // ensure the attribute is actually a container type
0187             traits::make_container(attr_);
0188 
0189             Iterator iter_local = first;
0190             fail_function f(iter_local, last, context, skipper);
0191             if (!parse_container(detail::make_pass_container(f, attr_)))
0192                 return false;
0193 
0194             first = f.first;
0195             return true;
0196         }
0197 
0198         template <typename Context>
0199         info what(Context& context) const
0200         {
0201             return info("repeat", subject.what(context));
0202         }
0203 
0204         Subject subject;
0205         LoopIter iter;
0206     };
0207 
0208     ///////////////////////////////////////////////////////////////////////////
0209     // Parser generators: make_xxx function (objects)
0210     ///////////////////////////////////////////////////////////////////////////
0211     template <typename Subject, typename Modifiers>
0212     struct make_directive<tag::repeat, Subject, Modifiers>
0213     {
0214         typedef kleene<Subject> result_type;
0215         result_type operator()(unused_type, Subject const& subject, unused_type) const
0216         {
0217             return result_type(subject);
0218         }
0219     };
0220 
0221     template <typename T, typename Subject, typename Modifiers>
0222     struct make_directive<
0223         terminal_ex<tag::repeat, fusion::vector1<T> >, Subject, Modifiers>
0224     {
0225         typedef exact_iterator<T> iterator_type;
0226         typedef repeat_parser<Subject, iterator_type> result_type;
0227 
0228         template <typename Terminal>
0229         result_type operator()(
0230             Terminal const& term, Subject const& subject, unused_type) const
0231         {
0232             return result_type(subject, fusion::at_c<0>(term.args));
0233         }
0234     };
0235 
0236     template <typename T, typename Subject, typename Modifiers>
0237     struct make_directive<
0238         terminal_ex<tag::repeat, fusion::vector2<T, T> >, Subject, Modifiers>
0239     {
0240         typedef finite_iterator<T> iterator_type;
0241         typedef repeat_parser<Subject, iterator_type> result_type;
0242 
0243         template <typename Terminal>
0244         result_type operator()(
0245             Terminal const& term, Subject const& subject, unused_type) const
0246         {
0247             return result_type(subject,
0248                 iterator_type(
0249                     fusion::at_c<0>(term.args)
0250                   , fusion::at_c<1>(term.args)
0251                 )
0252             );
0253         }
0254     };
0255 
0256     template <typename T, typename Subject, typename Modifiers>
0257     struct make_directive<
0258         terminal_ex<tag::repeat
0259         , fusion::vector2<T, inf_type> >, Subject, Modifiers>
0260     {
0261         typedef infinite_iterator<T> iterator_type;
0262         typedef repeat_parser<Subject, iterator_type> result_type;
0263 
0264         template <typename Terminal>
0265         result_type operator()(
0266             Terminal const& term, Subject const& subject, unused_type) const
0267         {
0268             return result_type(subject, fusion::at_c<0>(term.args));
0269         }
0270     };
0271 }}}
0272 
0273 namespace boost { namespace spirit { namespace traits
0274 {
0275     ///////////////////////////////////////////////////////////////////////////
0276     template <typename Subject, typename LoopIter>
0277     struct has_semantic_action<qi::repeat_parser<Subject, LoopIter> >
0278       : unary_has_semantic_action<Subject> {};
0279 
0280     ///////////////////////////////////////////////////////////////////////////
0281     template <typename Subject, typename LoopIter, typename Attribute
0282       , typename Context, typename Iterator>
0283     struct handles_container<qi::repeat_parser<Subject, LoopIter>
0284           , Attribute, Context, Iterator>
0285       : mpl::true_ {};
0286 }}}
0287 
0288 #endif