1 /*=============================================================================
2 Copyright (c) 1998-2003 Joel de Guzman
3 Copyright (c) 2003 Martin Wille
4 http://spirit.sourceforge.net/
6 Distributed under the Boost Software License, Version 1.0. (See accompanying
7 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8 =============================================================================*/
9 #if !defined(BOOST_SPIRIT_PRIMITIVES_HPP)
10 #define BOOST_SPIRIT_PRIMITIVES_HPP
12 #include <boost/ref.hpp>
13 #include <boost/spirit/home/classic/namespace.hpp>
14 #include <boost/spirit/home/classic/core/assert.hpp>
15 #include <boost/spirit/home/classic/core/parser.hpp>
16 #include <boost/spirit/home/classic/core/composite/impl/directives.ipp>
17 #include <boost/spirit/home/classic/core/primitives/impl/primitives.ipp>
20 #pragma warning (push)
21 #pragma warning(disable : 4512)
24 namespace boost { namespace spirit {
26 BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
28 ///////////////////////////////////////////////////////////////////////////
32 ///////////////////////////////////////////////////////////////////////////
33 template <typename DerivedT>
34 struct char_parser : public parser<DerivedT>
36 typedef DerivedT self_t;
37 template <typename ScannerT>
40 typedef typename match_result<
42 typename ScannerT::value_t
46 template <typename ScannerT>
47 typename parser_result<self_t, ScannerT>::type
48 parse(ScannerT const& scan) const
50 typedef typename ScannerT::value_t value_t;
51 typedef typename ScannerT::iterator_t iterator_t;
56 if (this->derived().test(ch))
58 iterator_t save(scan.first);
60 return scan.create_match(1, ch, save, scan.first);
63 return scan.no_match();
67 ///////////////////////////////////////////////////////////////////////////
69 // negation of char_parsers
71 ///////////////////////////////////////////////////////////////////////////
72 template <typename PositiveT>
73 struct negated_char_parser
74 : public char_parser<negated_char_parser<PositiveT> >
76 typedef negated_char_parser<PositiveT> self_t;
77 typedef PositiveT positive_t;
79 negated_char_parser(positive_t const& p)
80 : positive(p.derived()) {}
85 return !positive.test(ch);
88 positive_t const positive;
91 template <typename ParserT>
92 inline negated_char_parser<ParserT>
93 operator~(char_parser<ParserT> const& p)
95 return negated_char_parser<ParserT>(p.derived());
98 template <typename ParserT>
100 operator~(negated_char_parser<ParserT> const& n)
105 ///////////////////////////////////////////////////////////////////////////
109 ///////////////////////////////////////////////////////////////////////////
110 template <typename CharT = char>
111 struct chlit : public char_parser<chlit<CharT> >
116 template <typename T>
117 bool test(T ch_) const
125 template <typename CharT>
129 return chlit<CharT>(ch);
132 // This should take care of ch_p("a") "bugs"
133 template <typename CharT, std::size_t N>
135 ch_p(CharT const (& str)[N])
137 // ch_p's argument should be a single character or a null-terminated
138 // string with a single character
139 BOOST_STATIC_ASSERT(N < 3);
140 return chlit<CharT>(str[0]);
143 ///////////////////////////////////////////////////////////////////////////
147 ///////////////////////////////////////////////////////////////////////////
148 template <typename CharT = char>
149 struct range : public char_parser<range<CharT> >
151 range(CharT first_, CharT last_)
152 : first(first_), last(last_)
154 BOOST_SPIRIT_ASSERT(!(last < first));
157 template <typename T>
158 bool test(T ch) const
160 return !(CharT(ch) < first) && !(last < CharT(ch));
167 template <typename CharT>
169 range_p(CharT first, CharT last)
171 return range<CharT>(first, last);
174 ///////////////////////////////////////////////////////////////////////////
178 ///////////////////////////////////////////////////////////////////////////
179 template <typename IteratorT = char const*>
180 class chseq : public parser<chseq<IteratorT> >
184 typedef chseq<IteratorT> self_t;
186 chseq(IteratorT first_, IteratorT last_)
187 : first(first_), last(last_) {}
189 chseq(IteratorT first_)
190 : first(first_), last(impl::get_last(first_)) {}
192 template <typename ScannerT>
193 typename parser_result<self_t, ScannerT>::type
194 parse(ScannerT const& scan) const
196 typedef typename boost::unwrap_reference<IteratorT>::type striter_t;
197 typedef typename parser_result<self_t, ScannerT>::type result_t;
198 return impl::string_parser_parse<result_t>(
210 template <typename CharT>
211 inline chseq<CharT const*>
212 chseq_p(CharT const* str)
214 return chseq<CharT const*>(str);
217 template <typename IteratorT>
218 inline chseq<IteratorT>
219 chseq_p(IteratorT first, IteratorT last)
221 return chseq<IteratorT>(first, last);
224 ///////////////////////////////////////////////////////////////////////////
228 ///////////////////////////////////////////////////////////////////////////
229 template <typename IteratorT = char const*>
230 class strlit : public parser<strlit<IteratorT> >
234 typedef strlit<IteratorT> self_t;
236 strlit(IteratorT first, IteratorT last)
237 : seq(first, last) {}
239 strlit(IteratorT first)
242 template <typename ScannerT>
243 typename parser_result<self_t, ScannerT>::type
244 parse(ScannerT const& scan) const
246 typedef typename parser_result<self_t, ScannerT>::type result_t;
247 return impl::contiguous_parser_parse<result_t>
253 chseq<IteratorT> seq;
256 template <typename CharT>
257 inline strlit<CharT const*>
258 str_p(CharT const* str)
260 return strlit<CharT const*>(str);
263 template <typename CharT>
264 inline strlit<CharT *>
267 return strlit<CharT *>(str);
270 template <typename IteratorT>
271 inline strlit<IteratorT>
272 str_p(IteratorT first, IteratorT last)
274 return strlit<IteratorT>(first, last);
277 // This should take care of str_p('a') "bugs"
278 template <typename CharT>
282 return chlit<CharT>(ch);
285 ///////////////////////////////////////////////////////////////////////////
287 // nothing_parser class
289 ///////////////////////////////////////////////////////////////////////////
290 struct nothing_parser : public parser<nothing_parser>
292 typedef nothing_parser self_t;
296 template <typename ScannerT>
297 typename parser_result<self_t, ScannerT>::type
298 parse(ScannerT const& scan) const
300 return scan.no_match();
304 nothing_parser const nothing_p = nothing_parser();
306 ///////////////////////////////////////////////////////////////////////////
308 // anychar_parser class
310 ///////////////////////////////////////////////////////////////////////////
311 struct anychar_parser : public char_parser<anychar_parser>
313 typedef anychar_parser self_t;
317 template <typename CharT>
318 bool test(CharT) const
324 anychar_parser const anychar_p = anychar_parser();
326 inline nothing_parser
327 operator~(anychar_parser)
332 ///////////////////////////////////////////////////////////////////////////
334 // alnum_parser class
336 ///////////////////////////////////////////////////////////////////////////
337 struct alnum_parser : public char_parser<alnum_parser>
339 typedef alnum_parser self_t;
343 template <typename CharT>
344 bool test(CharT ch) const
346 return impl::isalnum_(ch);
350 alnum_parser const alnum_p = alnum_parser();
352 ///////////////////////////////////////////////////////////////////////////
354 // alpha_parser class
356 ///////////////////////////////////////////////////////////////////////////
357 struct alpha_parser : public char_parser<alpha_parser>
359 typedef alpha_parser self_t;
363 template <typename CharT>
364 bool test(CharT ch) const
366 return impl::isalpha_(ch);
370 alpha_parser const alpha_p = alpha_parser();
372 ///////////////////////////////////////////////////////////////////////////
374 // cntrl_parser class
376 ///////////////////////////////////////////////////////////////////////////
377 struct cntrl_parser : public char_parser<cntrl_parser>
379 typedef cntrl_parser self_t;
383 template <typename CharT>
384 bool test(CharT ch) const
386 return impl::iscntrl_(ch);
390 cntrl_parser const cntrl_p = cntrl_parser();
392 ///////////////////////////////////////////////////////////////////////////
394 // digit_parser class
396 ///////////////////////////////////////////////////////////////////////////
397 struct digit_parser : public char_parser<digit_parser>
399 typedef digit_parser self_t;
403 template <typename CharT>
404 bool test(CharT ch) const
406 return impl::isdigit_(ch);
410 digit_parser const digit_p = digit_parser();
412 ///////////////////////////////////////////////////////////////////////////
414 // graph_parser class
416 ///////////////////////////////////////////////////////////////////////////
417 struct graph_parser : public char_parser<graph_parser>
419 typedef graph_parser self_t;
423 template <typename CharT>
424 bool test(CharT ch) const
426 return impl::isgraph_(ch);
430 graph_parser const graph_p = graph_parser();
432 ///////////////////////////////////////////////////////////////////////////
434 // lower_parser class
436 ///////////////////////////////////////////////////////////////////////////
437 struct lower_parser : public char_parser<lower_parser>
439 typedef lower_parser self_t;
443 template <typename CharT>
444 bool test(CharT ch) const
446 return impl::islower_(ch);
450 lower_parser const lower_p = lower_parser();
452 ///////////////////////////////////////////////////////////////////////////
454 // print_parser class
456 ///////////////////////////////////////////////////////////////////////////
457 struct print_parser : public char_parser<print_parser>
459 typedef print_parser self_t;
463 template <typename CharT>
464 bool test(CharT ch) const
466 return impl::isprint_(ch);
470 print_parser const print_p = print_parser();
472 ///////////////////////////////////////////////////////////////////////////
474 // punct_parser class
476 ///////////////////////////////////////////////////////////////////////////
477 struct punct_parser : public char_parser<punct_parser>
479 typedef punct_parser self_t;
483 template <typename CharT>
484 bool test(CharT ch) const
486 return impl::ispunct_(ch);
490 punct_parser const punct_p = punct_parser();
492 ///////////////////////////////////////////////////////////////////////////
494 // blank_parser class
496 ///////////////////////////////////////////////////////////////////////////
497 struct blank_parser : public char_parser<blank_parser>
499 typedef blank_parser self_t;
503 template <typename CharT>
504 bool test(CharT ch) const
506 return impl::isblank_(ch);
510 blank_parser const blank_p = blank_parser();
512 ///////////////////////////////////////////////////////////////////////////
514 // space_parser class
516 ///////////////////////////////////////////////////////////////////////////
517 struct space_parser : public char_parser<space_parser>
519 typedef space_parser self_t;
523 template <typename CharT>
524 bool test(CharT ch) const
526 return impl::isspace_(ch);
530 space_parser const space_p = space_parser();
532 ///////////////////////////////////////////////////////////////////////////
534 // upper_parser class
536 ///////////////////////////////////////////////////////////////////////////
537 struct upper_parser : public char_parser<upper_parser>
539 typedef upper_parser self_t;
543 template <typename CharT>
544 bool test(CharT ch) const
546 return impl::isupper_(ch);
550 upper_parser const upper_p = upper_parser();
552 ///////////////////////////////////////////////////////////////////////////
554 // xdigit_parser class
556 ///////////////////////////////////////////////////////////////////////////
557 struct xdigit_parser : public char_parser<xdigit_parser>
559 typedef xdigit_parser self_t;
563 template <typename CharT>
564 bool test(CharT ch) const
566 return impl::isxdigit_(ch);
570 xdigit_parser const xdigit_p = xdigit_parser();
572 ///////////////////////////////////////////////////////////////////////////
574 // eol_parser class (contributed by Martin Wille)
576 ///////////////////////////////////////////////////////////////////////////
577 struct eol_parser : public parser<eol_parser>
579 typedef eol_parser self_t;
583 template <typename ScannerT>
584 typename parser_result<self_t, ScannerT>::type
585 parse(ScannerT const& scan) const
587 typename ScannerT::iterator_t save = scan.first;
590 if (!scan.at_end() && *scan == '\r') // CR
596 // Don't call skipper here
597 if (scan.first != scan.last && *scan == '\n') // LF
604 return scan.create_match(len, nil_t(), save, scan.first);
605 return scan.no_match();
609 eol_parser const eol_p = eol_parser();
611 ///////////////////////////////////////////////////////////////////////////
613 // end_parser class (suggested by Markus Schoepflin)
615 ///////////////////////////////////////////////////////////////////////////
616 struct end_parser : public parser<end_parser>
618 typedef end_parser self_t;
622 template <typename ScannerT>
623 typename parser_result<self_t, ScannerT>::type
624 parse(ScannerT const& scan) const
627 return scan.empty_match();
628 return scan.no_match();
632 end_parser const end_p = end_parser();
634 ///////////////////////////////////////////////////////////////////////////
636 // the pizza_p parser :-)
638 ///////////////////////////////////////////////////////////////////////////
639 inline strlit<char const*> const
640 pizza_p(char const* your_favorite_pizza)
642 return your_favorite_pizza;
645 BOOST_SPIRIT_CLASSIC_NAMESPACE_END
647 }} // namespace BOOST_SPIRIT_CLASSIC_NS
650 #pragma warning (pop)