Line data Source code
1 : /*=============================================================================
2 : Copyright (c) 1998-2003 Joel de Guzman
3 : Copyright (c) 2003 Martin Wille
4 : http://spirit.sourceforge.net/
5 :
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
11 :
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>
18 :
19 : #ifdef BOOST_MSVC
20 : #pragma warning (push)
21 : #pragma warning(disable : 4512)
22 : #endif
23 :
24 : namespace boost { namespace spirit {
25 :
26 : BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
27 :
28 : ///////////////////////////////////////////////////////////////////////////
29 : //
30 : // char_parser class
31 : //
32 : ///////////////////////////////////////////////////////////////////////////
33 : template <typename DerivedT>
34 : struct char_parser : public parser<DerivedT>
35 : {
36 : typedef DerivedT self_t;
37 : template <typename ScannerT>
38 : struct result
39 : {
40 : typedef typename match_result<
41 : ScannerT,
42 : typename ScannerT::value_t
43 : >::type type;
44 : };
45 :
46 : template <typename ScannerT>
47 : typename parser_result<self_t, ScannerT>::type
48 0 : parse(ScannerT const& scan) const
49 : {
50 : typedef typename ScannerT::value_t value_t;
51 : typedef typename ScannerT::iterator_t iterator_t;
52 : typedef scanner_policies<
53 : no_skipper_iteration_policy<
54 : BOOST_DEDUCED_TYPENAME ScannerT::iteration_policy_t>,
55 : BOOST_DEDUCED_TYPENAME ScannerT::match_policy_t,
56 : BOOST_DEDUCED_TYPENAME ScannerT::action_policy_t
57 : > policies_t;
58 :
59 0 : if (!scan.at_end())
60 : {
61 0 : value_t ch = *scan;
62 0 : if (this->derived().test(ch))
63 : {
64 0 : iterator_t save(scan.first);
65 0 : ++scan.change_policies(policies_t(scan));
66 0 : return scan.create_match(1, ch, save, scan.first);
67 : }
68 : }
69 0 : return scan.no_match();
70 : }
71 : };
72 :
73 : ///////////////////////////////////////////////////////////////////////////
74 : //
75 : // negation of char_parsers
76 : //
77 : ///////////////////////////////////////////////////////////////////////////
78 : template <typename PositiveT>
79 : struct negated_char_parser
80 : : public char_parser<negated_char_parser<PositiveT> >
81 : {
82 : typedef negated_char_parser<PositiveT> self_t;
83 : typedef PositiveT positive_t;
84 :
85 : negated_char_parser(positive_t const& p)
86 : : positive(p.derived()) {}
87 :
88 : template <typename T>
89 : bool test(T ch) const
90 : {
91 : return !positive.test(ch);
92 : }
93 :
94 : positive_t const positive;
95 : };
96 :
97 : template <typename ParserT>
98 : inline negated_char_parser<ParserT>
99 : operator~(char_parser<ParserT> const& p)
100 : {
101 : return negated_char_parser<ParserT>(p.derived());
102 : }
103 :
104 : template <typename ParserT>
105 : inline ParserT
106 : operator~(negated_char_parser<ParserT> const& n)
107 : {
108 : return n.positive;
109 : }
110 :
111 : ///////////////////////////////////////////////////////////////////////////
112 : //
113 : // chlit class
114 : //
115 : ///////////////////////////////////////////////////////////////////////////
116 : template <typename CharT = char>
117 : struct chlit : public char_parser<chlit<CharT> >
118 : {
119 0 : chlit(CharT ch_)
120 : : ch(ch_) {}
121 :
122 : template <typename T>
123 0 : bool test(T ch_) const
124 : {
125 0 : return ch_ == ch;
126 : }
127 :
128 : CharT ch;
129 : };
130 :
131 : template <typename CharT>
132 : inline chlit<CharT>
133 0 : ch_p(CharT ch)
134 : {
135 0 : return chlit<CharT>(ch);
136 : }
137 :
138 : // This should take care of ch_p("a") "bugs"
139 : template <typename CharT, std::size_t N>
140 : inline chlit<CharT>
141 : ch_p(CharT const (& str)[N])
142 : {
143 : // ch_p's argument should be a single character or a null-terminated
144 : // string with a single character
145 : BOOST_STATIC_ASSERT(N < 3);
146 : return chlit<CharT>(str[0]);
147 : }
148 :
149 : ///////////////////////////////////////////////////////////////////////////
150 : //
151 : // range class
152 : //
153 : ///////////////////////////////////////////////////////////////////////////
154 : template <typename CharT = char>
155 : struct range : public char_parser<range<CharT> >
156 : {
157 : range(CharT first_, CharT last_)
158 : : first(first_), last(last_)
159 : {
160 : BOOST_SPIRIT_ASSERT(!(last < first));
161 : }
162 :
163 : template <typename T>
164 : bool test(T ch) const
165 : {
166 : return !(CharT(ch) < first) && !(last < CharT(ch));
167 : }
168 :
169 : CharT first;
170 : CharT last;
171 : };
172 :
173 : template <typename CharT>
174 : inline range<CharT>
175 : range_p(CharT first, CharT last)
176 : {
177 : return range<CharT>(first, last);
178 : }
179 :
180 : ///////////////////////////////////////////////////////////////////////////
181 : //
182 : // chseq class
183 : //
184 : ///////////////////////////////////////////////////////////////////////////
185 : template <typename IteratorT = char const*>
186 : class chseq : public parser<chseq<IteratorT> >
187 : {
188 : public:
189 :
190 : typedef chseq<IteratorT> self_t;
191 :
192 : chseq(IteratorT first_, IteratorT last_)
193 : : first(first_), last(last_) {}
194 :
195 : chseq(IteratorT first_)
196 : : first(first_), last(impl::get_last(first_)) {}
197 :
198 : template <typename ScannerT>
199 : typename parser_result<self_t, ScannerT>::type
200 : parse(ScannerT const& scan) const
201 : {
202 : typedef typename boost::unwrap_reference<IteratorT>::type striter_t;
203 : typedef typename parser_result<self_t, ScannerT>::type result_t;
204 : return impl::string_parser_parse<result_t>(
205 : striter_t(first),
206 : striter_t(last),
207 : scan);
208 : }
209 :
210 : private:
211 :
212 : IteratorT first;
213 : IteratorT last;
214 : };
215 :
216 : template <typename CharT>
217 : inline chseq<CharT const*>
218 : chseq_p(CharT const* str)
219 : {
220 : return chseq<CharT const*>(str);
221 : }
222 :
223 : template <typename IteratorT>
224 : inline chseq<IteratorT>
225 : chseq_p(IteratorT first, IteratorT last)
226 : {
227 : return chseq<IteratorT>(first, last);
228 : }
229 :
230 : ///////////////////////////////////////////////////////////////////////////
231 : //
232 : // strlit class
233 : //
234 : ///////////////////////////////////////////////////////////////////////////
235 : template <typename IteratorT = char const*>
236 : class strlit : public parser<strlit<IteratorT> >
237 : {
238 : public:
239 :
240 : typedef strlit<IteratorT> self_t;
241 :
242 : strlit(IteratorT first, IteratorT last)
243 : : seq(first, last) {}
244 :
245 : strlit(IteratorT first)
246 : : seq(first) {}
247 :
248 : template <typename ScannerT>
249 : typename parser_result<self_t, ScannerT>::type
250 : parse(ScannerT const& scan) const
251 : {
252 : typedef typename parser_result<self_t, ScannerT>::type result_t;
253 : return impl::contiguous_parser_parse<result_t>
254 : (seq, scan, scan);
255 : }
256 :
257 : private:
258 :
259 : chseq<IteratorT> seq;
260 : };
261 :
262 : template <typename CharT>
263 : inline strlit<CharT const*>
264 : str_p(CharT const* str)
265 : {
266 : return strlit<CharT const*>(str);
267 : }
268 :
269 : template <typename CharT>
270 : inline strlit<CharT *>
271 : str_p(CharT * str)
272 : {
273 : return strlit<CharT *>(str);
274 : }
275 :
276 : template <typename IteratorT>
277 : inline strlit<IteratorT>
278 : str_p(IteratorT first, IteratorT last)
279 : {
280 : return strlit<IteratorT>(first, last);
281 : }
282 :
283 : // This should take care of str_p('a') "bugs"
284 : template <typename CharT>
285 : inline chlit<CharT>
286 : str_p(CharT ch)
287 : {
288 : return chlit<CharT>(ch);
289 : }
290 :
291 : ///////////////////////////////////////////////////////////////////////////
292 : //
293 : // nothing_parser class
294 : //
295 : ///////////////////////////////////////////////////////////////////////////
296 : struct nothing_parser : public parser<nothing_parser>
297 : {
298 : typedef nothing_parser self_t;
299 :
300 : nothing_parser() {}
301 :
302 : template <typename ScannerT>
303 : typename parser_result<self_t, ScannerT>::type
304 : parse(ScannerT const& scan) const
305 : {
306 : return scan.no_match();
307 : }
308 : };
309 :
310 : nothing_parser const nothing_p = nothing_parser();
311 :
312 : ///////////////////////////////////////////////////////////////////////////
313 : //
314 : // anychar_parser class
315 : //
316 : ///////////////////////////////////////////////////////////////////////////
317 : struct anychar_parser : public char_parser<anychar_parser>
318 : {
319 : typedef anychar_parser self_t;
320 :
321 : anychar_parser() {}
322 :
323 : template <typename CharT>
324 0 : bool test(CharT) const
325 : {
326 : return true;
327 : }
328 : };
329 :
330 : anychar_parser const anychar_p = anychar_parser();
331 :
332 : inline nothing_parser
333 : operator~(anychar_parser)
334 : {
335 : return nothing_p;
336 : }
337 :
338 : ///////////////////////////////////////////////////////////////////////////
339 : //
340 : // alnum_parser class
341 : //
342 : ///////////////////////////////////////////////////////////////////////////
343 : struct alnum_parser : public char_parser<alnum_parser>
344 : {
345 : typedef alnum_parser self_t;
346 :
347 : alnum_parser() {}
348 :
349 : template <typename CharT>
350 : bool test(CharT ch) const
351 : {
352 : return impl::isalnum_(ch);
353 : }
354 : };
355 :
356 : alnum_parser const alnum_p = alnum_parser();
357 :
358 : ///////////////////////////////////////////////////////////////////////////
359 : //
360 : // alpha_parser class
361 : //
362 : ///////////////////////////////////////////////////////////////////////////
363 : struct alpha_parser : public char_parser<alpha_parser>
364 : {
365 : typedef alpha_parser self_t;
366 :
367 : alpha_parser() {}
368 :
369 : template <typename CharT>
370 : bool test(CharT ch) const
371 : {
372 : return impl::isalpha_(ch);
373 : }
374 : };
375 :
376 : alpha_parser const alpha_p = alpha_parser();
377 :
378 : ///////////////////////////////////////////////////////////////////////////
379 : //
380 : // cntrl_parser class
381 : //
382 : ///////////////////////////////////////////////////////////////////////////
383 : struct cntrl_parser : public char_parser<cntrl_parser>
384 : {
385 : typedef cntrl_parser self_t;
386 :
387 : cntrl_parser() {}
388 :
389 : template <typename CharT>
390 : bool test(CharT ch) const
391 : {
392 : return impl::iscntrl_(ch);
393 : }
394 : };
395 :
396 : cntrl_parser const cntrl_p = cntrl_parser();
397 :
398 : ///////////////////////////////////////////////////////////////////////////
399 : //
400 : // digit_parser class
401 : //
402 : ///////////////////////////////////////////////////////////////////////////
403 : struct digit_parser : public char_parser<digit_parser>
404 : {
405 : typedef digit_parser self_t;
406 :
407 : digit_parser() {}
408 :
409 : template <typename CharT>
410 : bool test(CharT ch) const
411 : {
412 : return impl::isdigit_(ch);
413 : }
414 : };
415 :
416 : digit_parser const digit_p = digit_parser();
417 :
418 : ///////////////////////////////////////////////////////////////////////////
419 : //
420 : // graph_parser class
421 : //
422 : ///////////////////////////////////////////////////////////////////////////
423 : struct graph_parser : public char_parser<graph_parser>
424 : {
425 : typedef graph_parser self_t;
426 :
427 : graph_parser() {}
428 :
429 : template <typename CharT>
430 : bool test(CharT ch) const
431 : {
432 : return impl::isgraph_(ch);
433 : }
434 : };
435 :
436 : graph_parser const graph_p = graph_parser();
437 :
438 : ///////////////////////////////////////////////////////////////////////////
439 : //
440 : // lower_parser class
441 : //
442 : ///////////////////////////////////////////////////////////////////////////
443 : struct lower_parser : public char_parser<lower_parser>
444 : {
445 : typedef lower_parser self_t;
446 :
447 : lower_parser() {}
448 :
449 : template <typename CharT>
450 : bool test(CharT ch) const
451 : {
452 : return impl::islower_(ch);
453 : }
454 : };
455 :
456 : lower_parser const lower_p = lower_parser();
457 :
458 : ///////////////////////////////////////////////////////////////////////////
459 : //
460 : // print_parser class
461 : //
462 : ///////////////////////////////////////////////////////////////////////////
463 : struct print_parser : public char_parser<print_parser>
464 : {
465 : typedef print_parser self_t;
466 :
467 : print_parser() {}
468 :
469 : template <typename CharT>
470 : bool test(CharT ch) const
471 : {
472 : return impl::isprint_(ch);
473 : }
474 : };
475 :
476 : print_parser const print_p = print_parser();
477 :
478 : ///////////////////////////////////////////////////////////////////////////
479 : //
480 : // punct_parser class
481 : //
482 : ///////////////////////////////////////////////////////////////////////////
483 : struct punct_parser : public char_parser<punct_parser>
484 : {
485 : typedef punct_parser self_t;
486 :
487 : punct_parser() {}
488 :
489 : template <typename CharT>
490 : bool test(CharT ch) const
491 : {
492 : return impl::ispunct_(ch);
493 : }
494 : };
495 :
496 : punct_parser const punct_p = punct_parser();
497 :
498 : ///////////////////////////////////////////////////////////////////////////
499 : //
500 : // blank_parser class
501 : //
502 : ///////////////////////////////////////////////////////////////////////////
503 : struct blank_parser : public char_parser<blank_parser>
504 : {
505 : typedef blank_parser self_t;
506 :
507 : blank_parser() {}
508 :
509 : template <typename CharT>
510 : bool test(CharT ch) const
511 : {
512 : return impl::isblank_(ch);
513 : }
514 : };
515 :
516 : blank_parser const blank_p = blank_parser();
517 :
518 : ///////////////////////////////////////////////////////////////////////////
519 : //
520 : // space_parser class
521 : //
522 : ///////////////////////////////////////////////////////////////////////////
523 : struct space_parser : public char_parser<space_parser>
524 : {
525 : typedef space_parser self_t;
526 :
527 : space_parser() {}
528 :
529 : template <typename CharT>
530 : bool test(CharT ch) const
531 : {
532 : return impl::isspace_(ch);
533 : }
534 : };
535 :
536 : space_parser const space_p = space_parser();
537 :
538 : ///////////////////////////////////////////////////////////////////////////
539 : //
540 : // upper_parser class
541 : //
542 : ///////////////////////////////////////////////////////////////////////////
543 : struct upper_parser : public char_parser<upper_parser>
544 : {
545 : typedef upper_parser self_t;
546 :
547 : upper_parser() {}
548 :
549 : template <typename CharT>
550 : bool test(CharT ch) const
551 : {
552 : return impl::isupper_(ch);
553 : }
554 : };
555 :
556 : upper_parser const upper_p = upper_parser();
557 :
558 : ///////////////////////////////////////////////////////////////////////////
559 : //
560 : // xdigit_parser class
561 : //
562 : ///////////////////////////////////////////////////////////////////////////
563 : struct xdigit_parser : public char_parser<xdigit_parser>
564 : {
565 : typedef xdigit_parser self_t;
566 :
567 : xdigit_parser() {}
568 :
569 : template <typename CharT>
570 : bool test(CharT ch) const
571 : {
572 : return impl::isxdigit_(ch);
573 : }
574 : };
575 :
576 : xdigit_parser const xdigit_p = xdigit_parser();
577 :
578 : ///////////////////////////////////////////////////////////////////////////
579 : //
580 : // eol_parser class (contributed by Martin Wille)
581 : //
582 : ///////////////////////////////////////////////////////////////////////////
583 : struct eol_parser : public parser<eol_parser>
584 : {
585 : typedef eol_parser self_t;
586 :
587 : eol_parser() {}
588 :
589 : template <typename ScannerT>
590 : typename parser_result<self_t, ScannerT>::type
591 : parse(ScannerT const& scan) const
592 : {
593 : typedef scanner_policies<
594 : no_skipper_iteration_policy<
595 : BOOST_DEDUCED_TYPENAME ScannerT::iteration_policy_t>,
596 : BOOST_DEDUCED_TYPENAME ScannerT::match_policy_t,
597 : BOOST_DEDUCED_TYPENAME ScannerT::action_policy_t
598 : > policies_t;
599 :
600 : typename ScannerT::iterator_t save = scan.first;
601 : std::size_t len = 0;
602 :
603 : if (!scan.at_end() && *scan == '\r') // CR
604 : {
605 : ++scan.change_policies(policies_t(scan));
606 : ++len;
607 : }
608 :
609 : // Don't call skipper here
610 : if (scan.first != scan.last && *scan == '\n') // LF
611 : {
612 : ++scan.change_policies(policies_t(scan));
613 : ++len;
614 : }
615 :
616 : if (len)
617 : return scan.create_match(len, nil_t(), save, scan.first);
618 : return scan.no_match();
619 : }
620 : };
621 :
622 : eol_parser const eol_p = eol_parser();
623 :
624 : ///////////////////////////////////////////////////////////////////////////
625 : //
626 : // end_parser class (suggested by Markus Schoepflin)
627 : //
628 : ///////////////////////////////////////////////////////////////////////////
629 : struct end_parser : public parser<end_parser>
630 : {
631 : typedef end_parser self_t;
632 :
633 : end_parser() {}
634 :
635 : template <typename ScannerT>
636 : typename parser_result<self_t, ScannerT>::type
637 : parse(ScannerT const& scan) const
638 : {
639 : if (scan.at_end())
640 : return scan.empty_match();
641 : return scan.no_match();
642 : }
643 : };
644 :
645 : end_parser const end_p = end_parser();
646 :
647 : ///////////////////////////////////////////////////////////////////////////
648 : //
649 : // the pizza_p parser :-)
650 : //
651 : ///////////////////////////////////////////////////////////////////////////
652 : inline strlit<char const*> const
653 : pizza_p(char const* your_favorite_pizza)
654 : {
655 : return your_favorite_pizza;
656 : }
657 :
658 : BOOST_SPIRIT_CLASSIC_NAMESPACE_END
659 :
660 : }} // namespace BOOST_SPIRIT_CLASSIC_NS
661 :
662 : #ifdef BOOST_MSVC
663 : #pragma warning (pop)
664 : #endif
665 :
666 : #endif
|