source: NonGTP/Boost/boost/spirit/core/primitives/primitives.hpp @ 857

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