• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
parseboost::spirit::char_parser48         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             if (!scan.at_end())
60             {
61                 value_t ch = *scan;
62                 if (this->derived().test(ch))
63                 {
64                     iterator_t save(scan.first);
65                     ++scan.change_policies(policies_t(scan));
66                     return scan.create_match(1, ch, save, scan.first);
67                 }
68             }
69             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 
negated_char_parserboost::spirit::negated_char_parser85         negated_char_parser(positive_t const& p)
86         : positive(p.derived()) {}
87 
88         template <typename T>
testboost::spirit::negated_char_parser89         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>
operator ~(char_parser<ParserT> const & p)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
operator ~(negated_char_parser<ParserT> const & n)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     {
chlitboost::spirit::chlit119         chlit(CharT ch_)
120         : ch(ch_) {}
121 
122         template <typename T>
testboost::spirit::chlit123         bool test(T ch_) const
124         {
125             return ch_ == ch;
126         }
127 
128         CharT   ch;
129     };
130 
131     template <typename CharT>
132     inline chlit<CharT>
ch_p(CharT ch)133     ch_p(CharT ch)
134     {
135         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>
ch_p(CharT const (& str)[N])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     {
rangeboost::spirit::range157         range(CharT first_, CharT last_)
158         : first(first_), last(last_)
159         {
160             BOOST_SPIRIT_ASSERT(!(last < first));
161         }
162 
163         template <typename T>
testboost::spirit::range164         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>
range_p(CharT first,CharT last)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 
chseq(IteratorT first_,IteratorT last_)192         chseq(IteratorT first_, IteratorT last_)
193         : first(first_), last(last_) {}
194 
chseq(IteratorT first_)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
parse(ScannerT const & scan) const200         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*>
chseq_p(CharT const * str)218     chseq_p(CharT const* str)
219     {
220         return chseq<CharT const*>(str);
221     }
222 
223     template <typename IteratorT>
224     inline chseq<IteratorT>
chseq_p(IteratorT first,IteratorT last)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 
strlit(IteratorT first,IteratorT last)242         strlit(IteratorT first, IteratorT last)
243         : seq(first, last) {}
244 
strlit(IteratorT first)245         strlit(IteratorT first)
246         : seq(first) {}
247 
248         template <typename ScannerT>
249         typename parser_result<self_t, ScannerT>::type
parse(ScannerT const & scan) const250         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*>
str_p(CharT const * str)264     str_p(CharT const* str)
265     {
266         return strlit<CharT const*>(str);
267     }
268 
269     template <typename CharT>
270     inline strlit<CharT *>
str_p(CharT * str)271     str_p(CharT * str)
272     {
273         return strlit<CharT *>(str);
274     }
275 
276     template <typename IteratorT>
277     inline strlit<IteratorT>
str_p(IteratorT first,IteratorT last)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>
str_p(CharT ch)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 
nothing_parserboost::spirit::nothing_parser300         nothing_parser() {}
301 
302         template <typename ScannerT>
303         typename parser_result<self_t, ScannerT>::type
parseboost::spirit::nothing_parser304         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 
anychar_parserboost::spirit::anychar_parser321         anychar_parser() {}
322 
323         template <typename CharT>
testboost::spirit::anychar_parser324         bool test(CharT) const
325         {
326             return true;
327         }
328     };
329 
330     anychar_parser const anychar_p = anychar_parser();
331 
332     inline nothing_parser
operator ~(anychar_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 
alnum_parserboost::spirit::alnum_parser347         alnum_parser() {}
348 
349         template <typename CharT>
testboost::spirit::alnum_parser350         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 
alpha_parserboost::spirit::alpha_parser367         alpha_parser() {}
368 
369         template <typename CharT>
testboost::spirit::alpha_parser370         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 
cntrl_parserboost::spirit::cntrl_parser387         cntrl_parser() {}
388 
389         template <typename CharT>
testboost::spirit::cntrl_parser390         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 
digit_parserboost::spirit::digit_parser407         digit_parser() {}
408 
409         template <typename CharT>
testboost::spirit::digit_parser410         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 
graph_parserboost::spirit::graph_parser427         graph_parser() {}
428 
429         template <typename CharT>
testboost::spirit::graph_parser430         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 
lower_parserboost::spirit::lower_parser447         lower_parser() {}
448 
449         template <typename CharT>
testboost::spirit::lower_parser450         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 
print_parserboost::spirit::print_parser467         print_parser() {}
468 
469         template <typename CharT>
testboost::spirit::print_parser470         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 
punct_parserboost::spirit::punct_parser487         punct_parser() {}
488 
489         template <typename CharT>
testboost::spirit::punct_parser490         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 
blank_parserboost::spirit::blank_parser507         blank_parser() {}
508 
509         template <typename CharT>
testboost::spirit::blank_parser510         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 
space_parserboost::spirit::space_parser527         space_parser() {}
528 
529         template <typename CharT>
testboost::spirit::space_parser530         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 
upper_parserboost::spirit::upper_parser547         upper_parser() {}
548 
549         template <typename CharT>
testboost::spirit::upper_parser550         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 
xdigit_parserboost::spirit::xdigit_parser567         xdigit_parser() {}
568 
569         template <typename CharT>
testboost::spirit::xdigit_parser570         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 
eol_parserboost::spirit::eol_parser587         eol_parser() {}
588 
589         template <typename ScannerT>
590         typename parser_result<self_t, ScannerT>::type
parseboost::spirit::eol_parser591         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 
end_parserboost::spirit::end_parser633         end_parser() {}
634 
635         template <typename ScannerT>
636         typename parser_result<self_t, ScannerT>::type
parseboost::spirit::end_parser637         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
pizza_p(char const * your_favorite_pizza)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
667