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