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