Line data Source code
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 0 : 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> it_policy_t;
102 : typedef scanner_policies<it_policy_t> scan_policies_t;
103 : typedef scanner<IteratorT, scan_policies_t> scanner_t;
104 :
105 0 : it_policy_t iter_policy(skip);
106 0 : scan_policies_t policies(iter_policy);
107 0 : IteratorT first = first_;
108 0 : scanner_t scan(first, last, policies);
109 0 : match<nil_t> hit = p.parse(scan);
110 0 : return parse_info<IteratorT>(
111 0 : first, hit, hit && (first == last),
112 0 : 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 0 : parse(
122 : IteratorT const& first_,
123 : IteratorT const& last,
124 : ParserT const& p,
125 : space_parser const&)
126 : {
127 : typedef skipper_iteration_policy<> it_policy_t;
128 : typedef scanner_policies<it_policy_t> scan_policies_t;
129 : typedef scanner<IteratorT, scan_policies_t> scanner_t;
130 :
131 0 : IteratorT first = first_;
132 0 : scanner_t scan(first, last);
133 0 : match<nil_t> hit = p.parse(scan);
134 0 : return parse_info<IteratorT>(
135 0 : first, hit, hit && (first == last),
136 0 : 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 0 : 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 0 : 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 0 : parse(
166 : CharT const* str,
167 : parser<ParserT> const& p,
168 : parser<SkipT> const& skip)
169 : {
170 0 : CharT const* last = str;
171 0 : while (*last)
172 0 : last++;
173 0 : return parse(str, last, p, skip);
174 : }
175 :
176 : BOOST_SPIRIT_CLASSIC_NAMESPACE_END
177 :
178 : }} // namespace boost::spirit
179 :
180 : #endif
181 :
|