1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/ossrv_pub/boost_apis/boost/spirit/utility/loops.hpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,313 @@
1.4 +/*=============================================================================
1.5 + Copyright (c) 1998-2003 Joel de Guzman
1.6 + Copyright (c) 2002 Raghavendra Satish
1.7 + Copyright (c) 2002 Jeff Westfahl
1.8 + http://spirit.sourceforge.net/
1.9 +
1.10 + Use, modification and distribution is subject to the Boost Software
1.11 + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
1.12 + http://www.boost.org/LICENSE_1_0.txt)
1.13 +=============================================================================*/
1.14 +#if !defined(BOOST_SPIRIT_LOOPS_HPP)
1.15 +#define BOOST_SPIRIT_LOOPS_HPP
1.16 +
1.17 +///////////////////////////////////////////////////////////////////////////////
1.18 +#include <boost/spirit/core/parser.hpp>
1.19 +#include <boost/spirit/core/composite/composite.hpp>
1.20 +
1.21 +///////////////////////////////////////////////////////////////////////////////
1.22 +namespace boost { namespace spirit {
1.23 +
1.24 + ///////////////////////////////////////////////////////////////////////////
1.25 + //
1.26 + // fixed_loop class
1.27 + //
1.28 + // This class takes care of the construct:
1.29 + //
1.30 + // repeat_p (exact) [p]
1.31 + //
1.32 + // where 'p' is a parser and 'exact' is the number of times to
1.33 + // repeat. The parser iterates over the input exactly 'exact' times.
1.34 + // The parse function fails if the parser does not match the input
1.35 + // exactly 'exact' times.
1.36 + //
1.37 + // This class is parametizable and can accept constant arguments
1.38 + // (e.g. repeat_p (5) [p]) as well as references to variables (e.g.
1.39 + // repeat_p (ref (n)) [p]).
1.40 + //
1.41 + ///////////////////////////////////////////////////////////////////////////
1.42 + template <typename ParserT, typename ExactT>
1.43 + class fixed_loop
1.44 + : public unary<ParserT, parser <fixed_loop <ParserT, ExactT> > >
1.45 + {
1.46 + public:
1.47 +
1.48 + typedef fixed_loop<ParserT, ExactT> self_t;
1.49 + typedef unary<ParserT, parser<self_t> > base_t;
1.50 +
1.51 + fixed_loop (ParserT const & subject, ExactT const & exact)
1.52 + : base_t(subject), m_exact(exact) {}
1.53 +
1.54 + template <typename ScannerT>
1.55 + typename parser_result <self_t, ScannerT>::type
1.56 + parse (ScannerT const & scan) const
1.57 + {
1.58 + typedef typename parser_result<self_t, ScannerT>::type result_t;
1.59 + result_t hit = scan.empty_match();
1.60 + std::size_t n = m_exact;
1.61 +
1.62 + for (std::size_t i = 0; i < n; ++i)
1.63 + {
1.64 + if (result_t next = this->subject().parse(scan))
1.65 + {
1.66 + scan.concat_match(hit, next);
1.67 + }
1.68 + else
1.69 + {
1.70 + return scan.no_match();
1.71 + }
1.72 + }
1.73 +
1.74 + return hit;
1.75 + }
1.76 +
1.77 + template <typename ScannerT>
1.78 + struct result
1.79 + {
1.80 + typedef typename match_result<ScannerT, nil_t>::type type;
1.81 + };
1.82 +
1.83 + private:
1.84 +
1.85 + ExactT m_exact;
1.86 + };
1.87 +
1.88 + ///////////////////////////////////////////////////////////////////////////////
1.89 + //
1.90 + // finite_loop class
1.91 + //
1.92 + // This class takes care of the construct:
1.93 + //
1.94 + // repeat_p (min, max) [p]
1.95 + //
1.96 + // where 'p' is a parser, 'min' and 'max' specifies the minimum and
1.97 + // maximum iterations over 'p'. The parser iterates over the input
1.98 + // at least 'min' times and at most 'max' times. The parse function
1.99 + // fails if the parser does not match the input at least 'min' times
1.100 + // and at most 'max' times.
1.101 + //
1.102 + // This class is parametizable and can accept constant arguments
1.103 + // (e.g. repeat_p (5, 10) [p]) as well as references to variables
1.104 + // (e.g. repeat_p (ref (n1), ref (n2)) [p]).
1.105 + //
1.106 + ///////////////////////////////////////////////////////////////////////////////
1.107 + template <typename ParserT, typename MinT, typename MaxT>
1.108 + class finite_loop
1.109 + : public unary<ParserT, parser<finite_loop<ParserT, MinT, MaxT> > >
1.110 + {
1.111 + public:
1.112 +
1.113 + typedef finite_loop <ParserT, MinT, MaxT> self_t;
1.114 + typedef unary<ParserT, parser<self_t> > base_t;
1.115 +
1.116 + finite_loop (ParserT const & subject, MinT const & min, MaxT const & max)
1.117 + : base_t(subject), m_min(min), m_max(max) {}
1.118 +
1.119 + template <typename ScannerT>
1.120 + typename parser_result <self_t, ScannerT>::type
1.121 + parse(ScannerT const & scan) const
1.122 + {
1.123 + BOOST_SPIRIT_ASSERT(m_min <= m_max);
1.124 + typedef typename parser_result<self_t, ScannerT>::type result_t;
1.125 + result_t hit = scan.empty_match();
1.126 +
1.127 + std::size_t n1 = m_min;
1.128 + std::size_t n2 = m_max;
1.129 +
1.130 + for (std::size_t i = 0; i < n2; ++i)
1.131 + {
1.132 + typename ScannerT::iterator_t save = scan.first;
1.133 + result_t next = this->subject().parse(scan);
1.134 +
1.135 + if (!next)
1.136 + {
1.137 + if (i >= n1)
1.138 + {
1.139 + scan.first = save;
1.140 + break;
1.141 + }
1.142 + else
1.143 + {
1.144 + return scan.no_match();
1.145 + }
1.146 + }
1.147 +
1.148 + scan.concat_match(hit, next);
1.149 + }
1.150 +
1.151 + return hit;
1.152 + }
1.153 +
1.154 + template <typename ScannerT>
1.155 + struct result
1.156 + {
1.157 + typedef typename match_result<ScannerT, nil_t>::type type;
1.158 + };
1.159 +
1.160 + private:
1.161 +
1.162 + MinT m_min;
1.163 + MaxT m_max;
1.164 + };
1.165 +
1.166 + ///////////////////////////////////////////////////////////////////////////////
1.167 + //
1.168 + // infinite_loop class
1.169 + //
1.170 + // This class takes care of the construct:
1.171 + //
1.172 + // repeat_p (min, more) [p]
1.173 + //
1.174 + // where 'p' is a parser, 'min' is the minimum iteration over 'p'
1.175 + // and more specifies that the iteration should proceed
1.176 + // indefinitely. The parser iterates over the input at least 'min'
1.177 + // times and continues indefinitely until 'p' fails or all of the
1.178 + // input is parsed. The parse function fails if the parser does not
1.179 + // match the input at least 'min' times.
1.180 + //
1.181 + // This class is parametizable and can accept constant arguments
1.182 + // (e.g. repeat_p (5, more) [p]) as well as references to variables
1.183 + // (e.g. repeat_p (ref (n), more) [p]).
1.184 + //
1.185 + ///////////////////////////////////////////////////////////////////////////////
1.186 +
1.187 + struct more_t {};
1.188 + more_t const more = more_t ();
1.189 +
1.190 + template <typename ParserT, typename MinT>
1.191 + class infinite_loop
1.192 + : public unary<ParserT, parser<infinite_loop<ParserT, MinT> > >
1.193 + {
1.194 + public:
1.195 +
1.196 + typedef infinite_loop <ParserT, MinT> self_t;
1.197 + typedef unary<ParserT, parser<self_t> > base_t;
1.198 +
1.199 + infinite_loop (
1.200 + ParserT const& subject,
1.201 + MinT const& min,
1.202 + more_t const&
1.203 + )
1.204 + : base_t(subject), m_min(min) {}
1.205 +
1.206 + template <typename ScannerT>
1.207 + typename parser_result <self_t, ScannerT>::type
1.208 + parse(ScannerT const & scan) const
1.209 + {
1.210 + typedef typename parser_result<self_t, ScannerT>::type result_t;
1.211 + result_t hit = scan.empty_match();
1.212 + std::size_t n = m_min;
1.213 +
1.214 + for (std::size_t i = 0; ; ++i)
1.215 + {
1.216 + typename ScannerT::iterator_t save = scan.first;
1.217 + result_t next = this->subject().parse(scan);
1.218 +
1.219 + if (!next)
1.220 + {
1.221 + if (i >= n)
1.222 + {
1.223 + scan.first = save;
1.224 + break;
1.225 + }
1.226 + else
1.227 + {
1.228 + return scan.no_match();
1.229 + }
1.230 + }
1.231 +
1.232 + scan.concat_match(hit, next);
1.233 + }
1.234 +
1.235 + return hit;
1.236 + }
1.237 +
1.238 + template <typename ScannerT>
1.239 + struct result
1.240 + {
1.241 + typedef typename match_result<ScannerT, nil_t>::type type;
1.242 + };
1.243 +
1.244 + private:
1.245 +
1.246 + MinT m_min;
1.247 + };
1.248 +
1.249 + template <typename ExactT>
1.250 + struct fixed_loop_gen
1.251 + {
1.252 + fixed_loop_gen (ExactT const & exact)
1.253 + : m_exact (exact) {}
1.254 +
1.255 + template <typename ParserT>
1.256 + fixed_loop <ParserT, ExactT>
1.257 + operator[](parser <ParserT> const & subject) const
1.258 + {
1.259 + return fixed_loop <ParserT, ExactT> (subject.derived (), m_exact);
1.260 + }
1.261 +
1.262 + ExactT m_exact;
1.263 + };
1.264 +
1.265 + namespace impl {
1.266 +
1.267 + template <typename ParserT, typename MinT, typename MaxT>
1.268 + struct loop_traits
1.269 + {
1.270 + typedef typename mpl::if_<
1.271 + boost::is_same<MaxT, more_t>,
1.272 + infinite_loop<ParserT, MinT>,
1.273 + finite_loop<ParserT, MinT, MaxT>
1.274 + >::type type;
1.275 + };
1.276 +
1.277 + } // namespace impl
1.278 +
1.279 + template <typename MinT, typename MaxT>
1.280 + struct nonfixed_loop_gen
1.281 + {
1.282 + nonfixed_loop_gen (MinT min, MaxT max)
1.283 + : m_min (min), m_max (max) {}
1.284 +
1.285 + template <typename ParserT>
1.286 + typename impl::loop_traits<ParserT, MinT, MaxT>::type
1.287 + operator[](parser <ParserT> const & subject) const
1.288 + {
1.289 + typedef typename impl::loop_traits<ParserT, MinT, MaxT>::type ret_t;
1.290 + return ret_t(
1.291 + subject.derived(),
1.292 + m_min,
1.293 + m_max);
1.294 + }
1.295 +
1.296 + MinT m_min;
1.297 + MaxT m_max;
1.298 + };
1.299 +
1.300 + template <typename ExactT>
1.301 + fixed_loop_gen <ExactT>
1.302 + repeat_p(ExactT const & exact)
1.303 + {
1.304 + return fixed_loop_gen <ExactT> (exact);
1.305 + }
1.306 +
1.307 + template <typename MinT, typename MaxT>
1.308 + nonfixed_loop_gen <MinT, MaxT>
1.309 + repeat_p(MinT const & min, MaxT const & max)
1.310 + {
1.311 + return nonfixed_loop_gen <MinT, MaxT> (min, max);
1.312 + }
1.313 +
1.314 +}} // namespace boost::spirit
1.315 +
1.316 +#endif // #if !defined(BOOST_SPIRIT_LOOPS_HPP)