annotate DEPENDENCIES/generic/include/boost/spirit/home/classic/utility/loops.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents 2665513ce2d3
children
rev   line source
Chris@16 1 /*=============================================================================
Chris@16 2 Copyright (c) 1998-2003 Joel de Guzman
Chris@16 3 Copyright (c) 2002 Raghavendra Satish
Chris@16 4 Copyright (c) 2002 Jeff Westfahl
Chris@16 5 http://spirit.sourceforge.net/
Chris@16 6
Chris@16 7 Distributed under the Boost Software License, Version 1.0. (See accompanying
Chris@16 8 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Chris@16 9 =============================================================================*/
Chris@16 10 #if !defined(BOOST_SPIRIT_LOOPS_HPP)
Chris@16 11 #define BOOST_SPIRIT_LOOPS_HPP
Chris@16 12
Chris@16 13 ///////////////////////////////////////////////////////////////////////////////
Chris@16 14 #include <boost/spirit/home/classic/namespace.hpp>
Chris@16 15 #include <boost/spirit/home/classic/core/parser.hpp>
Chris@16 16 #include <boost/spirit/home/classic/core/composite/composite.hpp>
Chris@16 17
Chris@16 18 ///////////////////////////////////////////////////////////////////////////////
Chris@16 19 namespace boost { namespace spirit {
Chris@16 20
Chris@16 21 BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
Chris@16 22
Chris@16 23 ///////////////////////////////////////////////////////////////////////////
Chris@16 24 //
Chris@16 25 // fixed_loop class
Chris@16 26 //
Chris@16 27 // This class takes care of the construct:
Chris@16 28 //
Chris@16 29 // repeat_p (exact) [p]
Chris@16 30 //
Chris@16 31 // where 'p' is a parser and 'exact' is the number of times to
Chris@16 32 // repeat. The parser iterates over the input exactly 'exact' times.
Chris@16 33 // The parse function fails if the parser does not match the input
Chris@16 34 // exactly 'exact' times.
Chris@16 35 //
Chris@16 36 // This class is parametizable and can accept constant arguments
Chris@16 37 // (e.g. repeat_p (5) [p]) as well as references to variables (e.g.
Chris@16 38 // repeat_p (ref (n)) [p]).
Chris@16 39 //
Chris@16 40 ///////////////////////////////////////////////////////////////////////////
Chris@16 41 template <typename ParserT, typename ExactT>
Chris@16 42 class fixed_loop
Chris@16 43 : public unary<ParserT, parser <fixed_loop <ParserT, ExactT> > >
Chris@16 44 {
Chris@16 45 public:
Chris@16 46
Chris@16 47 typedef fixed_loop<ParserT, ExactT> self_t;
Chris@16 48 typedef unary<ParserT, parser<self_t> > base_t;
Chris@16 49
Chris@16 50 fixed_loop (ParserT const & subject_, ExactT const & exact)
Chris@16 51 : base_t(subject_), m_exact(exact) {}
Chris@16 52
Chris@16 53 template <typename ScannerT>
Chris@16 54 typename parser_result <self_t, ScannerT>::type
Chris@16 55 parse (ScannerT const & scan) const
Chris@16 56 {
Chris@16 57 typedef typename parser_result<self_t, ScannerT>::type result_t;
Chris@16 58 result_t hit = scan.empty_match();
Chris@16 59 std::size_t n = m_exact;
Chris@16 60
Chris@16 61 for (std::size_t i = 0; i < n; ++i)
Chris@16 62 {
Chris@16 63 if (result_t next = this->subject().parse(scan))
Chris@16 64 {
Chris@16 65 scan.concat_match(hit, next);
Chris@16 66 }
Chris@16 67 else
Chris@16 68 {
Chris@16 69 return scan.no_match();
Chris@16 70 }
Chris@16 71 }
Chris@16 72
Chris@16 73 return hit;
Chris@16 74 }
Chris@16 75
Chris@16 76 template <typename ScannerT>
Chris@16 77 struct result
Chris@16 78 {
Chris@16 79 typedef typename match_result<ScannerT, nil_t>::type type;
Chris@16 80 };
Chris@16 81
Chris@16 82 private:
Chris@16 83
Chris@16 84 ExactT m_exact;
Chris@16 85 };
Chris@16 86
Chris@16 87 ///////////////////////////////////////////////////////////////////////////////
Chris@16 88 //
Chris@16 89 // finite_loop class
Chris@16 90 //
Chris@16 91 // This class takes care of the construct:
Chris@16 92 //
Chris@16 93 // repeat_p (min, max) [p]
Chris@16 94 //
Chris@16 95 // where 'p' is a parser, 'min' and 'max' specifies the minimum and
Chris@16 96 // maximum iterations over 'p'. The parser iterates over the input
Chris@16 97 // at least 'min' times and at most 'max' times. The parse function
Chris@16 98 // fails if the parser does not match the input at least 'min' times
Chris@16 99 // and at most 'max' times.
Chris@16 100 //
Chris@16 101 // This class is parametizable and can accept constant arguments
Chris@16 102 // (e.g. repeat_p (5, 10) [p]) as well as references to variables
Chris@16 103 // (e.g. repeat_p (ref (n1), ref (n2)) [p]).
Chris@16 104 //
Chris@16 105 ///////////////////////////////////////////////////////////////////////////////
Chris@16 106 template <typename ParserT, typename MinT, typename MaxT>
Chris@16 107 class finite_loop
Chris@16 108 : public unary<ParserT, parser<finite_loop<ParserT, MinT, MaxT> > >
Chris@16 109 {
Chris@16 110 public:
Chris@16 111
Chris@16 112 typedef finite_loop <ParserT, MinT, MaxT> self_t;
Chris@16 113 typedef unary<ParserT, parser<self_t> > base_t;
Chris@16 114
Chris@16 115 finite_loop (ParserT const & subject_, MinT const & min, MaxT const & max)
Chris@16 116 : base_t(subject_), m_min(min), m_max(max) {}
Chris@16 117
Chris@16 118 template <typename ScannerT>
Chris@16 119 typename parser_result <self_t, ScannerT>::type
Chris@16 120 parse(ScannerT const & scan) const
Chris@16 121 {
Chris@16 122 BOOST_SPIRIT_ASSERT(m_min <= m_max);
Chris@16 123 typedef typename parser_result<self_t, ScannerT>::type result_t;
Chris@16 124 result_t hit = scan.empty_match();
Chris@16 125
Chris@16 126 std::size_t n1 = m_min;
Chris@16 127 std::size_t n2 = m_max;
Chris@16 128
Chris@16 129 for (std::size_t i = 0; i < n2; ++i)
Chris@16 130 {
Chris@16 131 typename ScannerT::iterator_t save = scan.first;
Chris@16 132 result_t next = this->subject().parse(scan);
Chris@16 133
Chris@16 134 if (!next)
Chris@16 135 {
Chris@16 136 if (i >= n1)
Chris@16 137 {
Chris@16 138 scan.first = save;
Chris@16 139 break;
Chris@16 140 }
Chris@16 141 else
Chris@16 142 {
Chris@16 143 return scan.no_match();
Chris@16 144 }
Chris@16 145 }
Chris@16 146
Chris@16 147 scan.concat_match(hit, next);
Chris@16 148 }
Chris@16 149
Chris@16 150 return hit;
Chris@16 151 }
Chris@16 152
Chris@16 153 template <typename ScannerT>
Chris@16 154 struct result
Chris@16 155 {
Chris@16 156 typedef typename match_result<ScannerT, nil_t>::type type;
Chris@16 157 };
Chris@16 158
Chris@16 159 private:
Chris@16 160
Chris@16 161 MinT m_min;
Chris@16 162 MaxT m_max;
Chris@16 163 };
Chris@16 164
Chris@16 165 ///////////////////////////////////////////////////////////////////////////////
Chris@16 166 //
Chris@16 167 // infinite_loop class
Chris@16 168 //
Chris@16 169 // This class takes care of the construct:
Chris@16 170 //
Chris@16 171 // repeat_p (min, more) [p]
Chris@16 172 //
Chris@16 173 // where 'p' is a parser, 'min' is the minimum iteration over 'p'
Chris@16 174 // and more specifies that the iteration should proceed
Chris@16 175 // indefinitely. The parser iterates over the input at least 'min'
Chris@16 176 // times and continues indefinitely until 'p' fails or all of the
Chris@16 177 // input is parsed. The parse function fails if the parser does not
Chris@16 178 // match the input at least 'min' times.
Chris@16 179 //
Chris@16 180 // This class is parametizable and can accept constant arguments
Chris@16 181 // (e.g. repeat_p (5, more) [p]) as well as references to variables
Chris@16 182 // (e.g. repeat_p (ref (n), more) [p]).
Chris@16 183 //
Chris@16 184 ///////////////////////////////////////////////////////////////////////////////
Chris@16 185
Chris@16 186 struct more_t {};
Chris@16 187 more_t const more = more_t ();
Chris@16 188
Chris@16 189 template <typename ParserT, typename MinT>
Chris@16 190 class infinite_loop
Chris@16 191 : public unary<ParserT, parser<infinite_loop<ParserT, MinT> > >
Chris@16 192 {
Chris@16 193 public:
Chris@16 194
Chris@16 195 typedef infinite_loop <ParserT, MinT> self_t;
Chris@16 196 typedef unary<ParserT, parser<self_t> > base_t;
Chris@16 197
Chris@16 198 infinite_loop (
Chris@16 199 ParserT const& subject_,
Chris@16 200 MinT const& min,
Chris@16 201 more_t const&
Chris@16 202 )
Chris@16 203 : base_t(subject_), m_min(min) {}
Chris@16 204
Chris@16 205 template <typename ScannerT>
Chris@16 206 typename parser_result <self_t, ScannerT>::type
Chris@16 207 parse(ScannerT const & scan) const
Chris@16 208 {
Chris@16 209 typedef typename parser_result<self_t, ScannerT>::type result_t;
Chris@16 210 result_t hit = scan.empty_match();
Chris@16 211 std::size_t n = m_min;
Chris@16 212
Chris@16 213 for (std::size_t i = 0; ; ++i)
Chris@16 214 {
Chris@16 215 typename ScannerT::iterator_t save = scan.first;
Chris@16 216 result_t next = this->subject().parse(scan);
Chris@16 217
Chris@16 218 if (!next)
Chris@16 219 {
Chris@16 220 if (i >= n)
Chris@16 221 {
Chris@16 222 scan.first = save;
Chris@16 223 break;
Chris@16 224 }
Chris@16 225 else
Chris@16 226 {
Chris@16 227 return scan.no_match();
Chris@16 228 }
Chris@16 229 }
Chris@16 230
Chris@16 231 scan.concat_match(hit, next);
Chris@16 232 }
Chris@16 233
Chris@16 234 return hit;
Chris@16 235 }
Chris@16 236
Chris@16 237 template <typename ScannerT>
Chris@16 238 struct result
Chris@16 239 {
Chris@16 240 typedef typename match_result<ScannerT, nil_t>::type type;
Chris@16 241 };
Chris@16 242
Chris@16 243 private:
Chris@16 244
Chris@16 245 MinT m_min;
Chris@16 246 };
Chris@16 247
Chris@16 248 template <typename ExactT>
Chris@16 249 struct fixed_loop_gen
Chris@16 250 {
Chris@16 251 fixed_loop_gen (ExactT const & exact)
Chris@16 252 : m_exact (exact) {}
Chris@16 253
Chris@16 254 template <typename ParserT>
Chris@16 255 fixed_loop <ParserT, ExactT>
Chris@16 256 operator[](parser <ParserT> const & subject_) const
Chris@16 257 {
Chris@16 258 return fixed_loop <ParserT, ExactT> (subject_.derived (), m_exact);
Chris@16 259 }
Chris@16 260
Chris@16 261 ExactT m_exact;
Chris@16 262 };
Chris@16 263
Chris@16 264 namespace impl {
Chris@16 265
Chris@16 266 template <typename ParserT, typename MinT, typename MaxT>
Chris@16 267 struct loop_traits
Chris@16 268 {
Chris@16 269 typedef typename mpl::if_<
Chris@16 270 boost::is_same<MaxT, more_t>,
Chris@16 271 infinite_loop<ParserT, MinT>,
Chris@16 272 finite_loop<ParserT, MinT, MaxT>
Chris@16 273 >::type type;
Chris@16 274 };
Chris@16 275
Chris@16 276 } // namespace impl
Chris@16 277
Chris@16 278 template <typename MinT, typename MaxT>
Chris@16 279 struct nonfixed_loop_gen
Chris@16 280 {
Chris@16 281 nonfixed_loop_gen (MinT min, MaxT max)
Chris@16 282 : m_min (min), m_max (max) {}
Chris@16 283
Chris@16 284 template <typename ParserT>
Chris@16 285 typename impl::loop_traits<ParserT, MinT, MaxT>::type
Chris@16 286 operator[](parser <ParserT> const & subject_) const
Chris@16 287 {
Chris@16 288 typedef typename impl::loop_traits<ParserT, MinT, MaxT>::type ret_t;
Chris@16 289 return ret_t(
Chris@16 290 subject_.derived(),
Chris@16 291 m_min,
Chris@16 292 m_max);
Chris@16 293 }
Chris@16 294
Chris@16 295 MinT m_min;
Chris@16 296 MaxT m_max;
Chris@16 297 };
Chris@16 298
Chris@16 299 template <typename ExactT>
Chris@16 300 fixed_loop_gen <ExactT>
Chris@16 301 repeat_p(ExactT const & exact)
Chris@16 302 {
Chris@16 303 return fixed_loop_gen <ExactT> (exact);
Chris@16 304 }
Chris@16 305
Chris@16 306 template <typename MinT, typename MaxT>
Chris@16 307 nonfixed_loop_gen <MinT, MaxT>
Chris@16 308 repeat_p(MinT const & min, MaxT const & max)
Chris@16 309 {
Chris@16 310 return nonfixed_loop_gen <MinT, MaxT> (min, max);
Chris@16 311 }
Chris@16 312
Chris@16 313 BOOST_SPIRIT_CLASSIC_NAMESPACE_END
Chris@16 314
Chris@16 315 }} // namespace BOOST_SPIRIT_CLASSIC_NS
Chris@16 316
Chris@16 317 #endif // #if !defined(BOOST_SPIRIT_LOOPS_HPP)