]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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_IPP) | |
10 | #define BOOST_SPIRIT_SKIPPER_IPP | |
11 | ||
12 | /////////////////////////////////////////////////////////////////////////////// | |
13 | namespace boost { namespace spirit { | |
14 | ||
15 | BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN | |
16 | ||
17 | struct space_parser; | |
18 | template <typename BaseT> | |
19 | struct no_skipper_iteration_policy; | |
20 | ||
21 | namespace impl | |
22 | { | |
23 | template <typename ST, typename ScannerT, typename BaseT> | |
24 | inline void | |
25 | skipper_skip( | |
26 | ST const& s, | |
27 | ScannerT const& scan, | |
28 | skipper_iteration_policy<BaseT> const&) | |
29 | { | |
30 | typedef scanner_policies< | |
31 | no_skipper_iteration_policy< | |
32 | BOOST_DEDUCED_TYPENAME ScannerT::iteration_policy_t>, | |
33 | BOOST_DEDUCED_TYPENAME ScannerT::match_policy_t, | |
34 | BOOST_DEDUCED_TYPENAME ScannerT::action_policy_t | |
35 | > policies_t; | |
36 | ||
37 | scanner<BOOST_DEDUCED_TYPENAME ScannerT::iterator_t, policies_t> | |
38 | scan2(scan.first, scan.last, policies_t(scan)); | |
39 | typedef typename ScannerT::iterator_t iterator_t; | |
40 | ||
41 | for (;;) | |
42 | { | |
43 | iterator_t save = scan.first; | |
44 | if (!s.parse(scan2)) | |
45 | { | |
46 | scan.first = save; | |
47 | break; | |
48 | } | |
49 | } | |
50 | } | |
51 | ||
52 | template <typename ST, typename ScannerT, typename BaseT> | |
53 | inline void | |
54 | skipper_skip( | |
55 | ST const& s, | |
56 | ScannerT const& scan, | |
57 | no_skipper_iteration_policy<BaseT> const&) | |
58 | { | |
59 | for (;;) | |
60 | { | |
61 | typedef typename ScannerT::iterator_t iterator_t; | |
62 | iterator_t save = scan.first; | |
63 | if (!s.parse(scan)) | |
64 | { | |
65 | scan.first = save; | |
66 | break; | |
67 | } | |
68 | } | |
69 | } | |
70 | ||
71 | template <typename ST, typename ScannerT> | |
72 | inline void | |
73 | skipper_skip( | |
74 | ST const& s, | |
75 | ScannerT const& scan, | |
76 | iteration_policy const&) | |
77 | { | |
78 | for (;;) | |
79 | { | |
80 | typedef typename ScannerT::iterator_t iterator_t; | |
81 | iterator_t save = scan.first; | |
82 | if (!s.parse(scan)) | |
83 | { | |
84 | scan.first = save; | |
85 | break; | |
86 | } | |
87 | } | |
88 | } | |
89 | ||
90 | template <typename SkipT> | |
91 | struct phrase_parser | |
92 | { | |
93 | template <typename IteratorT, typename ParserT> | |
94 | static parse_info<IteratorT> | |
95 | parse( | |
96 | IteratorT const& first_, | |
97 | IteratorT const& last, | |
98 | ParserT const& p, | |
99 | SkipT const& skip) | |
100 | { | |
101 | typedef skip_parser_iteration_policy<SkipT> iter_policy_t; | |
102 | typedef scanner_policies<iter_policy_t> scanner_policies_t; | |
103 | typedef scanner<IteratorT, scanner_policies_t> scanner_t; | |
104 | ||
105 | iter_policy_t iter_policy(skip); | |
106 | scanner_policies_t policies(iter_policy); | |
107 | IteratorT first = first_; | |
108 | scanner_t scan(first, last, policies); | |
109 | match<nil_t> hit = p.parse(scan); | |
110 | return parse_info<IteratorT>( | |
111 | first, hit, hit && (first == last), | |
112 | hit.length()); | |
113 | } | |
114 | }; | |
115 | ||
116 | template <> | |
117 | struct phrase_parser<space_parser> | |
118 | { | |
119 | template <typename IteratorT, typename ParserT> | |
120 | static parse_info<IteratorT> | |
121 | parse( | |
122 | IteratorT const& first_, | |
123 | IteratorT const& last, | |
124 | ParserT const& p, | |
125 | space_parser const&) | |
126 | { | |
127 | typedef skipper_iteration_policy<> iter_policy_t; | |
128 | typedef scanner_policies<iter_policy_t> scanner_policies_t; | |
129 | typedef scanner<IteratorT, scanner_policies_t> scanner_t; | |
130 | ||
131 | IteratorT first = first_; | |
132 | scanner_t scan(first, last); | |
133 | match<nil_t> hit = p.parse(scan); | |
134 | return parse_info<IteratorT>( | |
135 | first, hit, hit && (first == last), | |
136 | hit.length()); | |
137 | } | |
138 | }; | |
139 | } | |
140 | ||
141 | /////////////////////////////////////////////////////////////////////////// | |
142 | // | |
143 | // Free parse functions using the skippers | |
144 | // | |
145 | /////////////////////////////////////////////////////////////////////////// | |
146 | template <typename IteratorT, typename ParserT, typename SkipT> | |
147 | inline parse_info<IteratorT> | |
148 | parse( | |
149 | IteratorT const& first, | |
150 | IteratorT const& last, | |
151 | parser<ParserT> const& p, | |
152 | parser<SkipT> const& skip) | |
153 | { | |
154 | return impl::phrase_parser<SkipT>:: | |
155 | parse(first, last, p.derived(), skip.derived()); | |
156 | } | |
157 | ||
158 | /////////////////////////////////////////////////////////////////////////// | |
159 | // | |
160 | // Parse function for null terminated strings using the skippers | |
161 | // | |
162 | /////////////////////////////////////////////////////////////////////////// | |
163 | template <typename CharT, typename ParserT, typename SkipT> | |
164 | inline parse_info<CharT const*> | |
165 | parse( | |
166 | CharT const* str, | |
167 | parser<ParserT> const& p, | |
168 | parser<SkipT> const& skip) | |
169 | { | |
170 | CharT const* last = str; | |
171 | while (*last) | |
172 | last++; | |
173 | return parse(str, last, p, skip); | |
174 | } | |
175 | ||
176 | BOOST_SPIRIT_CLASSIC_NAMESPACE_END | |
177 | ||
178 | }} // namespace boost::spirit | |
179 | ||
180 | #endif | |
181 |