1 /*=============================================================================
2     Copyright (c) 1998-2003 Joel de Guzman
3     http://spirit.sourceforge.net/
4 
5   Distributed under the Boost Software License, Version 1.0. (See accompanying
6   file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 =============================================================================*/
8 #if !defined(BOOST_SPIRIT_SKIPPER_HPP)
9 #define BOOST_SPIRIT_SKIPPER_HPP
10 
11 ///////////////////////////////////////////////////////////////////////////////
12 #include <cctype>
13 
14 #include <boost/spirit/home/classic/namespace.hpp>
15 #include <boost/spirit/home/classic/core/scanner/scanner.hpp>
16 #include <boost/spirit/home/classic/core/primitives/impl/primitives.ipp>
17 
18 #include <boost/spirit/home/classic/core/scanner/skipper_fwd.hpp>
19 
20 namespace boost { namespace spirit {
21 
22 BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
23 
24     ///////////////////////////////////////////////////////////////////////////
25     //
26     //  skipper_iteration_policy class
27     //
28     ///////////////////////////////////////////////////////////////////////////
29     template <typename BaseT>
30     struct skipper_iteration_policy : public BaseT
31     {
32         typedef BaseT base_t;
33 
skipper_iteration_policyboost::spirit::skipper_iteration_policy34         skipper_iteration_policy()
35         : BaseT() {}
36 
37         template <typename PolicyT>
skipper_iteration_policyboost::spirit::skipper_iteration_policy38         skipper_iteration_policy(PolicyT const& other)
39         : BaseT(other) {}
40 
41         template <typename ScannerT>
42         void
advanceboost::spirit::skipper_iteration_policy43         advance(ScannerT const& scan) const
44         {
45             BaseT::advance(scan);
46             scan.skip(scan);
47         }
48 
49         template <typename ScannerT>
50         bool
at_endboost::spirit::skipper_iteration_policy51         at_end(ScannerT const& scan) const
52         {
53             scan.skip(scan);
54             return BaseT::at_end(scan);
55         }
56 
57         template <typename ScannerT>
58         void
skipboost::spirit::skipper_iteration_policy59         skip(ScannerT const& scan) const
60         {
61             while (!BaseT::at_end(scan) && impl::isspace_(BaseT::get(scan)))
62                 BaseT::advance(scan);
63         }
64     };
65 
66     ///////////////////////////////////////////////////////////////////////////
67     //
68     //  no_skipper_iteration_policy class
69     //
70     ///////////////////////////////////////////////////////////////////////////
71     template <typename BaseT>
72     struct no_skipper_iteration_policy : public BaseT
73     {
74         typedef BaseT base_t;
75 
no_skipper_iteration_policyboost::spirit::no_skipper_iteration_policy76         no_skipper_iteration_policy()
77         : BaseT() {}
78 
79         template <typename PolicyT>
no_skipper_iteration_policyboost::spirit::no_skipper_iteration_policy80         no_skipper_iteration_policy(PolicyT const& other)
81         : BaseT(other) {}
82 
83         template <typename ScannerT>
84         void
skipboost::spirit::no_skipper_iteration_policy85         skip(ScannerT const& /*scan*/) const {}
86     };
87 
88     ///////////////////////////////////////////////////////////////////////////
89     //
90     //  skip_parser_iteration_policy class
91     //
92     ///////////////////////////////////////////////////////////////////////////
93     namespace impl
94     {
95         template <typename ST, typename ScannerT, typename BaseT>
96         void
97         skipper_skip(
98             ST const& s,
99             ScannerT const& scan,
100             skipper_iteration_policy<BaseT> const&);
101 
102         template <typename ST, typename ScannerT, typename BaseT>
103         void
104         skipper_skip(
105             ST const& s,
106             ScannerT const& scan,
107             no_skipper_iteration_policy<BaseT> const&);
108 
109         template <typename ST, typename ScannerT>
110         void
111         skipper_skip(
112             ST const& s,
113             ScannerT const& scan,
114             iteration_policy const&);
115     }
116 
117     template <typename ParserT, typename BaseT>
118     class skip_parser_iteration_policy : public skipper_iteration_policy<BaseT>
119     {
120     public:
121 
122         typedef skipper_iteration_policy<BaseT> base_t;
123 
skip_parser_iteration_policy(ParserT const & skip_parser,base_t const & base=base_t ())124         skip_parser_iteration_policy(
125             ParserT const& skip_parser,
126             base_t const& base = base_t())
127         : base_t(base), subject(skip_parser) {}
128 
129         template <typename PolicyT>
skip_parser_iteration_policy(PolicyT const & other)130         skip_parser_iteration_policy(PolicyT const& other)
131         : base_t(other), subject(other.skipper()) {}
132 
133         template <typename ScannerT>
134         void
skip(ScannerT const & scan) const135         skip(ScannerT const& scan) const
136         {
137             impl::skipper_skip(subject, scan, scan);
138         }
139 
140         ParserT const&
skipper() const141         skipper() const
142         {
143             return subject;
144         }
145 
146     private:
147 
148         ParserT const& subject;
149     };
150 
151     ///////////////////////////////////////////////////////////////////////////////
152     //
153     //  Free parse functions using the skippers
154     //
155     ///////////////////////////////////////////////////////////////////////////////
156     template <typename IteratorT, typename ParserT, typename SkipT>
157     parse_info<IteratorT>
158     parse(
159         IteratorT const&        first,
160         IteratorT const&        last,
161         parser<ParserT> const&  p,
162         parser<SkipT> const&    skip);
163 
164     ///////////////////////////////////////////////////////////////////////////////
165     //
166     //  Parse function for null terminated strings using the skippers
167     //
168     ///////////////////////////////////////////////////////////////////////////////
169     template <typename CharT, typename ParserT, typename SkipT>
170     parse_info<CharT const*>
171     parse(
172         CharT const*            str,
173         parser<ParserT> const&  p,
174         parser<SkipT> const&    skip);
175 
176     ///////////////////////////////////////////////////////////////////////////////
177     //
178     //  phrase_scanner_t and wide_phrase_scanner_t
179     //
180     //      The most common scanners. Use these typedefs when you need
181     //      a scanner that skips white spaces.
182     //
183     ///////////////////////////////////////////////////////////////////////////////
184     typedef skipper_iteration_policy<>                  iter_policy_t;
185     typedef scanner_policies<iter_policy_t>             scanner_policies_t;
186     typedef scanner<char const*, scanner_policies_t>    phrase_scanner_t;
187     typedef scanner<wchar_t const*, scanner_policies_t> wide_phrase_scanner_t;
188 
189     ///////////////////////////////////////////////////////////////////////////////
190 
191 BOOST_SPIRIT_CLASSIC_NAMESPACE_END
192 
193 }} // namespace BOOST_SPIRIT_CLASSIC_NS
194 
195 #include <boost/spirit/home/classic/core/scanner/impl/skipper.ipp>
196 #endif
197 
198