diff options
Diffstat (limited to 'src/MoonP/parser.cpp')
-rw-r--r-- | src/MoonP/parser.cpp | 1923 |
1 files changed, 956 insertions, 967 deletions
diff --git a/src/MoonP/parser.cpp b/src/MoonP/parser.cpp index cb896c2..07f6e41 100644 --- a/src/MoonP/parser.cpp +++ b/src/MoonP/parser.cpp | |||
@@ -1,12 +1,13 @@ | |||
1 | /* Copyright (c) 2012, Achilleas Margaritis, modified by Jin Li | 1 | /* Copyright (c) 2012, Achilleas Margaritis, modified by Jin Li |
2 | All rights reserved. | 2 | All rights reserved. |
3 | 3 | ||
4 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: | 4 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: |
5 | 5 | ||
6 | Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. | 6 | Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. |
7 | Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. | ||
8 | 7 | ||
9 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ | 8 | Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. |
9 | |||
10 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.*/ | ||
10 | 11 | ||
11 | #include <cstdlib> | 12 | #include <cstdlib> |
12 | #include <cstring> | 13 | #include <cstring> |
@@ -24,25 +25,25 @@ namespace parserlib { | |||
24 | //internal private class that manages access to the public classes' internals. | 25 | //internal private class that manages access to the public classes' internals. |
25 | class _private { | 26 | class _private { |
26 | public: | 27 | public: |
27 | //get the internal expression object from the expression. | 28 | //get the internal expression object from the expression. |
28 | static _expr *get_expr(const expr &e) { | 29 | static _expr* get_expr(const expr& e) { |
29 | return e.m_expr; | 30 | return e.m_expr; |
30 | } | 31 | } |
31 | 32 | ||
32 | //create new expression from given expression | 33 | //create new expression from given expression |
33 | static expr construct_expr(_expr *e) { | 34 | static expr construct_expr(_expr* e) { |
34 | return e; | 35 | return e; |
35 | } | 36 | } |
36 | 37 | ||
37 | //get the internal expression object from the rule. | 38 | //get the internal expression object from the rule. |
38 | static _expr *get_expr(rule &r) { | 39 | static _expr* get_expr(rule& r) { |
39 | return r.m_expr; | 40 | return r.m_expr; |
40 | } | 41 | } |
41 | 42 | ||
42 | //get the internal parse proc from the rule. | 43 | //get the internal parse proc from the rule. |
43 | static parse_proc get_parse_proc(rule &r) { | 44 | static parse_proc get_parse_proc(rule& r) { |
44 | return r.m_parse_proc; | 45 | return r.m_parse_proc; |
45 | } | 46 | } |
46 | }; | 47 | }; |
47 | 48 | ||
48 | 49 | ||
@@ -52,39 +53,39 @@ class _context; | |||
52 | //parser state | 53 | //parser state |
53 | class _state { | 54 | class _state { |
54 | public: | 55 | public: |
55 | //position | 56 | //position |
56 | pos m_pos; | 57 | pos m_pos; |
57 | 58 | ||
58 | //size of match vector | 59 | //size of match vector |
59 | size_t m_matches; | 60 | size_t m_matches; |
60 | 61 | ||
61 | //constructor | 62 | //constructor |
62 | _state(_context &con); | 63 | _state(_context& con); |
63 | }; | 64 | }; |
64 | 65 | ||
65 | 66 | ||
66 | //match | 67 | //match |
67 | class _match { | 68 | class _match { |
68 | public: | 69 | public: |
69 | //rule matched | 70 | //rule matched |
70 | rule *m_rule; | 71 | rule* m_rule; |
71 | 72 | ||
72 | //begin position | 73 | //begin position |
73 | pos m_begin; | 74 | pos m_begin; |
74 | 75 | ||
75 | //end position | 76 | //end position |
76 | pos m_end; | 77 | pos m_end; |
77 | 78 | ||
78 | //null constructor | 79 | //null constructor |
79 | _match() {} | 80 | _match() {} |
80 | 81 | ||
81 | //constructor from parameters | 82 | //constructor from parameters |
82 | _match(rule *r, const pos &b, const pos &e) : | 83 | _match(rule* r, const pos& b, const pos& e) : |
83 | m_rule(r), | 84 | m_rule(r), |
84 | m_begin(b), | 85 | m_begin(b), |
85 | m_end(e) | 86 | m_end(e) |
86 | { | 87 | { |
87 | } | 88 | } |
88 | }; | 89 | }; |
89 | 90 | ||
90 | 91 | ||
@@ -98,226 +99,226 @@ public: | |||
98 | //user data | 99 | //user data |
99 | void* m_user_data; | 100 | void* m_user_data; |
100 | 101 | ||
101 | //current position | 102 | //current position |
102 | pos m_pos; | 103 | pos m_pos; |
103 | 104 | ||
104 | //error position | 105 | //error position |
105 | pos m_error_pos; | 106 | pos m_error_pos; |
106 | 107 | ||
107 | //input begin | 108 | //input begin |
108 | input::iterator m_begin; | 109 | input::iterator m_begin; |
109 | 110 | ||
110 | //input end | 111 | //input end |
111 | input::iterator m_end; | 112 | input::iterator m_end; |
112 | 113 | ||
113 | //matches | 114 | //matches |
114 | _match_vector m_matches; | 115 | _match_vector m_matches; |
115 | 116 | ||
116 | //constructor | 117 | //constructor |
117 | _context(input &i, void* ud) : | 118 | _context(input& i, void* ud) : |
118 | m_user_data(ud), | 119 | m_user_data(ud), |
119 | m_pos(i), | 120 | m_pos(i), |
120 | m_error_pos(i), | 121 | m_error_pos(i), |
121 | m_begin(i.begin()), | 122 | m_begin(i.begin()), |
122 | m_end(i.end()) | 123 | m_end(i.end()) |
123 | { | 124 | { |
124 | } | 125 | } |
125 | 126 | ||
126 | //check if the end is reached | 127 | //check if the end is reached |
127 | bool end() const { | 128 | bool end() const { |
128 | return m_pos.m_it == m_end; | 129 | return m_pos.m_it == m_end; |
129 | } | 130 | } |
130 | 131 | ||
131 | //get the current symbol | 132 | //get the current symbol |
132 | input::value_type symbol() const { | 133 | input::value_type symbol() const { |
133 | assert(!end()); | 134 | assert(!end()); |
134 | return *m_pos.m_it; | 135 | return *m_pos.m_it; |
135 | } | 136 | } |
136 | 137 | ||
137 | //set the longest possible error | 138 | //set the longest possible error |
138 | void set_error_pos() { | 139 | void set_error_pos() { |
139 | if (m_pos.m_it > m_error_pos.m_it) { | 140 | if (m_pos.m_it > m_error_pos.m_it) { |
140 | m_error_pos = m_pos; | 141 | m_error_pos = m_pos; |
141 | } | 142 | } |
142 | } | 143 | } |
143 | 144 | ||
144 | //next column | 145 | //next column |
145 | void next_col() { | 146 | void next_col() { |
146 | ++m_pos.m_it; | 147 | ++m_pos.m_it; |
147 | ++m_pos.m_col; | 148 | ++m_pos.m_col; |
148 | } | 149 | } |
149 | 150 | ||
150 | //next line | 151 | //next line |
151 | void next_line() { | 152 | void next_line() { |
152 | ++m_pos.m_line; | 153 | ++m_pos.m_line; |
153 | m_pos.m_col = 1; | 154 | m_pos.m_col = 1; |
154 | } | 155 | } |
155 | 156 | ||
156 | //restore the state | 157 | //restore the state |
157 | void restore(const _state &st) { | 158 | void restore(const _state& st) { |
158 | m_pos = st.m_pos; | 159 | m_pos = st.m_pos; |
159 | m_matches.resize(st.m_matches); | 160 | m_matches.resize(st.m_matches); |
160 | } | 161 | } |
161 | 162 | ||
162 | //parse non-term rule. | 163 | //parse non-term rule. |
163 | bool parse_non_term(rule &r); | 164 | bool parse_non_term(rule& r); |
164 | 165 | ||
165 | //parse term rule. | 166 | //parse term rule. |
166 | bool parse_term(rule &r); | 167 | bool parse_term(rule& r); |
167 | 168 | ||
168 | //execute all the parse procs | 169 | //execute all the parse procs |
169 | void do_parse_procs(void *d) const { | 170 | void do_parse_procs(void* d) const { |
170 | for(_match_vector::const_iterator it = m_matches.begin(); | 171 | for(_match_vector::const_iterator it = m_matches.begin(); |
171 | it != m_matches.end(); | 172 | it != m_matches.end(); |
172 | ++it) | 173 | ++it) |
173 | { | 174 | { |
174 | const _match &m = *it; | 175 | const _match &m = *it; |
175 | parse_proc p = _private::get_parse_proc(*m.m_rule); | 176 | parse_proc p = _private::get_parse_proc(*m.m_rule); |
176 | p(m.m_begin, m.m_end, d); | 177 | p(m.m_begin, m.m_end, d); |
177 | } | 178 | } |
178 | } | 179 | } |
179 | 180 | ||
180 | private: | 181 | private: |
181 | //parse non-term rule. | 182 | //parse non-term rule. |
182 | bool _parse_non_term(rule &r); | 183 | bool _parse_non_term(rule& r); |
183 | 184 | ||
184 | //parse term rule. | 185 | //parse term rule. |
185 | bool _parse_term(rule &r); | 186 | bool _parse_term(rule& r); |
186 | }; | 187 | }; |
187 | 188 | ||
188 | 189 | ||
189 | //base class for expressions | 190 | //base class for expressions |
190 | class _expr { | 191 | class _expr { |
191 | public: | 192 | public: |
192 | //destructor. | 193 | //destructor. |
193 | virtual ~_expr() { | 194 | virtual ~_expr() { |
194 | } | 195 | } |
195 | 196 | ||
196 | //parse with whitespace | 197 | //parse with whitespace |
197 | virtual bool parse_non_term(_context &con) const = 0; | 198 | virtual bool parse_non_term(_context& con) const = 0; |
198 | 199 | ||
199 | //parse terminal | 200 | //parse terminal |
200 | virtual bool parse_term(_context &con) const = 0; | 201 | virtual bool parse_term(_context& con) const = 0; |
201 | }; | 202 | }; |
202 | 203 | ||
203 | 204 | ||
204 | //single character expression. | 205 | //single character expression. |
205 | class _char : public _expr { | 206 | class _char : public _expr { |
206 | public: | 207 | public: |
207 | //constructor. | 208 | //constructor. |
208 | _char(char c) : | 209 | _char(char c) : |
209 | m_char(c) | 210 | m_char(c) |
210 | { | 211 | { |
211 | } | 212 | } |
212 | 213 | ||
213 | //parse with whitespace | 214 | //parse with whitespace |
214 | virtual bool parse_non_term(_context &con) const { | 215 | virtual bool parse_non_term(_context& con) const { |
215 | return _parse(con); | 216 | return _parse(con); |
216 | } | 217 | } |
217 | 218 | ||
218 | //parse terminal | 219 | //parse terminal |
219 | virtual bool parse_term(_context &con) const { | 220 | virtual bool parse_term(_context& con) const { |
220 | return _parse(con); | 221 | return _parse(con); |
221 | } | 222 | } |
222 | 223 | ||
223 | private: | 224 | private: |
224 | //character | 225 | //character |
225 | input::value_type m_char; | 226 | input::value_type m_char; |
226 | 227 | ||
227 | //internal parse | 228 | //internal parse |
228 | bool _parse(_context &con) const { | 229 | bool _parse(_context& con) const { |
229 | if (!con.end()) { | 230 | if (!con.end()) { |
230 | input::value_type ch = con.symbol(); | 231 | input::value_type ch = con.symbol(); |
231 | if (ch == m_char) { | 232 | if (ch == m_char) { |
232 | con.next_col(); | 233 | con.next_col(); |
233 | return true; | 234 | return true; |
234 | } | 235 | } |
235 | } | 236 | } |
236 | con.set_error_pos(); | 237 | con.set_error_pos(); |
237 | return false; | 238 | return false; |
238 | } | 239 | } |
239 | }; | 240 | }; |
240 | 241 | ||
241 | 242 | ||
242 | //string expression. | 243 | //string expression. |
243 | class _string : public _expr { | 244 | class _string : public _expr { |
244 | public: | 245 | public: |
245 | //constructor from ansi string. | 246 | //constructor from ansi string. |
246 | _string(const char *s) : | 247 | _string(const char* s) : |
247 | m_string(Converter{}.from_bytes(s)) | 248 | m_string(Converter{}.from_bytes(s)) |
248 | { | 249 | { |
249 | } | 250 | } |
250 | 251 | ||
251 | //parse with whitespace | 252 | //parse with whitespace |
252 | virtual bool parse_non_term(_context &con) const { | 253 | virtual bool parse_non_term(_context& con) const { |
253 | return _parse(con); | 254 | return _parse(con); |
254 | } | 255 | } |
255 | 256 | ||
256 | //parse terminal | 257 | //parse terminal |
257 | virtual bool parse_term(_context &con) const { | 258 | virtual bool parse_term(_context& con) const { |
258 | return _parse(con); | 259 | return _parse(con); |
259 | } | 260 | } |
260 | 261 | ||
261 | private: | 262 | private: |
262 | //string | 263 | //string |
263 | input m_string; | 264 | input m_string; |
264 | 265 | ||
265 | //parse the string | 266 | //parse the string |
266 | bool _parse(_context &con) const { | 267 | bool _parse(_context& con) const { |
267 | for(input::const_iterator it = m_string.begin(), | 268 | for(input::const_iterator it = m_string.begin(), |
268 | end = m_string.end();;) | 269 | end = m_string.end();;) |
269 | { | 270 | { |
270 | if (it == end) return true; | 271 | if (it == end) return true; |
271 | if (con.end()) break; | 272 | if (con.end()) break; |
272 | if (con.symbol() != *it) break; | 273 | if (con.symbol() != *it) break; |
273 | ++it; | 274 | ++it; |
274 | con.next_col(); | 275 | con.next_col(); |
275 | } | 276 | } |
276 | con.set_error_pos(); | 277 | con.set_error_pos(); |
277 | return false; | 278 | return false; |
278 | } | 279 | } |
279 | }; | 280 | }; |
280 | 281 | ||
281 | 282 | ||
282 | //set expression. | 283 | //set expression. |
283 | class _set : public _expr { | 284 | class _set : public _expr { |
284 | public: | 285 | public: |
285 | //constructor from ansi string. | 286 | //constructor from ansi string. |
286 | _set(const char *s) { | 287 | _set(const char* s) { |
287 | auto str = Converter{}.from_bytes(s); | 288 | auto str = Converter{}.from_bytes(s); |
288 | for (auto ch : str) { | 289 | for (auto ch : str) { |
289 | _add(ch); | 290 | _add(ch); |
290 | } | 291 | } |
291 | } | 292 | } |
292 | 293 | ||
293 | //constructor from range. | 294 | //constructor from range. |
294 | _set(int min, int max) { | 295 | _set(int min, int max) { |
295 | assert(min >= 0); | 296 | assert(min >= 0); |
296 | assert(min <= max); | 297 | assert(min <= max); |
297 | m_quick_set.resize((size_t)max + 1U); | 298 | m_quick_set.resize((size_t)max + 1U); |
298 | for(; min <= max; ++min) { | 299 | for(; min <= max; ++min) { |
299 | m_quick_set[(size_t)min] = true; | 300 | m_quick_set[(size_t)min] = true; |
300 | } | 301 | } |
301 | } | 302 | } |
302 | 303 | ||
303 | //parse with whitespace | 304 | //parse with whitespace |
304 | virtual bool parse_non_term(_context &con) const { | 305 | virtual bool parse_non_term(_context& con) const { |
305 | return _parse(con); | 306 | return _parse(con); |
306 | } | 307 | } |
307 | 308 | ||
308 | //parse terminal | 309 | //parse terminal |
309 | virtual bool parse_term(_context &con) const { | 310 | virtual bool parse_term(_context& con) const { |
310 | return _parse(con); | 311 | return _parse(con); |
311 | } | 312 | } |
312 | 313 | ||
313 | private: | 314 | private: |
314 | //set is kept as an array of flags, for quick access | 315 | //set is kept as an array of flags, for quick access |
315 | std::vector<bool> m_quick_set; | 316 | std::vector<bool> m_quick_set; |
316 | std::unordered_set<size_t> m_large_set; | 317 | std::unordered_set<size_t> m_large_set; |
317 | 318 | ||
318 | //add character | 319 | //add character |
319 | void _add(size_t i) { | 320 | void _add(size_t i) { |
320 | if (i <= m_quick_set.size() || i <= 255) { | 321 | if (i <= m_quick_set.size() || i <= 255) { |
321 | if (i >= m_quick_set.size()) { | 322 | if (i >= m_quick_set.size()) { |
322 | m_quick_set.resize(i + 1); | 323 | m_quick_set.resize(i + 1); |
323 | } | 324 | } |
@@ -325,66 +326,66 @@ private: | |||
325 | } else { | 326 | } else { |
326 | m_large_set.insert(i); | 327 | m_large_set.insert(i); |
327 | } | 328 | } |
328 | } | 329 | } |
329 | 330 | ||
330 | //internal parse | 331 | //internal parse |
331 | bool _parse(_context &con) const { | 332 | bool _parse(_context& con) const { |
332 | if (!con.end()) { | 333 | if (!con.end()) { |
333 | size_t ch = con.symbol(); | 334 | size_t ch = con.symbol(); |
334 | if (ch < m_quick_set.size()) { | 335 | if (ch < m_quick_set.size()) { |
335 | if (m_quick_set[ch]) { | 336 | if (m_quick_set[ch]) { |
336 | con.next_col(); | 337 | con.next_col(); |
337 | return true; | 338 | return true; |
338 | } | 339 | } |
339 | } else if (m_large_set.find(ch) != m_large_set.end()) { | 340 | } else if (m_large_set.find(ch) != m_large_set.end()) { |
340 | con.next_col(); | 341 | con.next_col(); |
341 | return true; | 342 | return true; |
342 | } | 343 | } |
343 | } | 344 | } |
344 | con.set_error_pos(); | 345 | con.set_error_pos(); |
345 | return false; | 346 | return false; |
346 | } | 347 | } |
347 | }; | 348 | }; |
348 | 349 | ||
349 | 350 | ||
350 | //base class for unary expressions | 351 | //base class for unary expressions |
351 | class _unary : public _expr { | 352 | class _unary : public _expr { |
352 | public: | 353 | public: |
353 | //constructor. | 354 | //constructor. |
354 | _unary(_expr *e) : | 355 | _unary(_expr* e) : |
355 | m_expr(e) | 356 | m_expr(e) |
356 | { | 357 | { |
357 | } | 358 | } |
358 | 359 | ||
359 | //destructor. | 360 | //destructor. |
360 | virtual ~_unary() { | 361 | virtual ~_unary() { |
361 | delete m_expr; | 362 | delete m_expr; |
362 | } | 363 | } |
363 | 364 | ||
364 | protected: | 365 | protected: |
365 | //expression | 366 | //expression |
366 | _expr *m_expr; | 367 | _expr *m_expr; |
367 | }; | 368 | }; |
368 | 369 | ||
369 | 370 | ||
370 | //terminal | 371 | //terminal |
371 | class _term : public _unary { | 372 | class _term : public _unary { |
372 | public: | 373 | public: |
373 | //constructor. | 374 | //constructor. |
374 | _term(_expr *e) : | 375 | _term(_expr* e) : |
375 | _unary(e) | 376 | _unary(e) |
376 | { | 377 | { |
377 | } | 378 | } |
378 | 379 | ||
379 | //parse with whitespace | 380 | //parse with whitespace |
380 | virtual bool parse_non_term(_context &con) const { | 381 | virtual bool parse_non_term(_context& con) const { |
381 | return m_expr->parse_term(con); | 382 | return m_expr->parse_term(con); |
382 | } | 383 | } |
383 | 384 | ||
384 | //parse terminal | 385 | //parse terminal |
385 | virtual bool parse_term(_context &con) const { | 386 | virtual bool parse_term(_context& con) const { |
386 | return m_expr->parse_term(con); | 387 | return m_expr->parse_term(con); |
387 | } | 388 | } |
388 | }; | 389 | }; |
389 | 390 | ||
390 | 391 | ||
@@ -392,14 +393,14 @@ public: | |||
392 | class _user : public _unary { | 393 | class _user : public _unary { |
393 | public: | 394 | public: |
394 | //constructor. | 395 | //constructor. |
395 | _user(_expr *e, const user_handler &callback) : | 396 | _user(_expr* e, const user_handler& callback) : |
396 | _unary(e), | 397 | _unary(e), |
397 | m_handler(callback) | 398 | m_handler(callback) |
398 | { | 399 | { |
399 | } | 400 | } |
400 | 401 | ||
401 | //parse with whitespace | 402 | //parse with whitespace |
402 | virtual bool parse_non_term(_context &con) const { | 403 | virtual bool parse_non_term(_context& con) const { |
403 | pos pos = con.m_pos; | 404 | pos pos = con.m_pos; |
404 | if (m_expr->parse_non_term(con)) { | 405 | if (m_expr->parse_non_term(con)) { |
405 | item_t item = {pos.m_it, con.m_pos.m_it, con.m_user_data}; | 406 | item_t item = {pos.m_it, con.m_pos.m_it, con.m_user_data}; |
@@ -409,7 +410,7 @@ public: | |||
409 | } | 410 | } |
410 | 411 | ||
411 | //parse terminal | 412 | //parse terminal |
412 | virtual bool parse_term(_context &con) const { | 413 | virtual bool parse_term(_context& con) const { |
413 | pos pos = con.m_pos; | 414 | pos pos = con.m_pos; |
414 | if (m_expr->parse_term(con)) { | 415 | if (m_expr->parse_term(con)) { |
415 | item_t item = {pos.m_it, con.m_pos.m_it, con.m_user_data}; | 416 | item_t item = {pos.m_it, con.m_pos.m_it, con.m_user_data}; |
@@ -425,333 +426,333 @@ private: | |||
425 | //loop 0 | 426 | //loop 0 |
426 | class _loop0 : public _unary { | 427 | class _loop0 : public _unary { |
427 | public: | 428 | public: |
428 | //constructor. | 429 | //constructor. |
429 | _loop0(_expr *e) : | 430 | _loop0(_expr* e) : |
430 | _unary(e) | 431 | _unary(e) |
431 | { | 432 | { |
432 | } | 433 | } |
433 | 434 | ||
434 | //parse with whitespace | 435 | //parse with whitespace |
435 | virtual bool parse_non_term(_context &con) const { | 436 | virtual bool parse_non_term(_context& con) const { |
436 | //if parsing of the first fails, restore the context and stop | 437 | //if parsing of the first fails, restore the context and stop |
437 | _state st(con); | 438 | _state st(con); |
438 | if (!m_expr->parse_non_term(con)) { | 439 | if (!m_expr->parse_non_term(con)) { |
439 | con.restore(st); | 440 | con.restore(st); |
440 | return true; | 441 | return true; |
441 | } | 442 | } |
442 | 443 | ||
443 | //parse the rest | 444 | //parse the rest |
444 | for(;;) { | 445 | for(;;) { |
445 | _state st(con); | 446 | _state st(con); |
446 | if (!m_expr->parse_non_term(con)) { | 447 | if (!m_expr->parse_non_term(con)) { |
447 | con.restore(st); | 448 | con.restore(st); |
448 | break; | 449 | break; |
449 | } | 450 | } |
450 | } | 451 | } |
451 | 452 | ||
452 | return true; | 453 | return true; |
453 | } | 454 | } |
454 | 455 | ||
455 | //parse terminal | 456 | //parse terminal |
456 | virtual bool parse_term(_context &con) const { | 457 | virtual bool parse_term(_context& con) const { |
457 | //if parsing of the first fails, restore the context and stop | 458 | //if parsing of the first fails, restore the context and stop |
458 | _state st(con); | 459 | _state st(con); |
459 | if (!m_expr->parse_term(con)) { | 460 | if (!m_expr->parse_term(con)) { |
460 | con.restore(st); | 461 | con.restore(st); |
461 | return true; | 462 | return true; |
462 | } | 463 | } |
463 | 464 | ||
464 | //parse the rest until no more parsing is possible | 465 | //parse the rest until no more parsing is possible |
465 | for(;;) { | 466 | for(;;) { |
466 | _state st(con); | 467 | _state st(con); |
467 | if (!m_expr->parse_term(con)) { | 468 | if (!m_expr->parse_term(con)) { |
468 | con.restore(st); | 469 | con.restore(st); |
469 | break; | 470 | break; |
470 | } | 471 | } |
471 | } | 472 | } |
472 | 473 | ||
473 | return true; | 474 | return true; |
474 | } | 475 | } |
475 | }; | 476 | }; |
476 | 477 | ||
477 | 478 | ||
478 | //loop 1 | 479 | //loop 1 |
479 | class _loop1 : public _unary { | 480 | class _loop1 : public _unary { |
480 | public: | 481 | public: |
481 | //constructor. | 482 | //constructor. |
482 | _loop1(_expr *e) : | 483 | _loop1(_expr* e) : |
483 | _unary(e) | 484 | _unary(e) |
484 | { | 485 | { |
485 | } | 486 | } |
486 | 487 | ||
487 | //parse with whitespace | 488 | //parse with whitespace |
488 | virtual bool parse_non_term(_context &con) const { | 489 | virtual bool parse_non_term(_context& con) const { |
489 | //parse the first; if the first fails, stop | 490 | //parse the first; if the first fails, stop |
490 | if (!m_expr->parse_non_term(con)) return false; | 491 | if (!m_expr->parse_non_term(con)) return false; |
491 | 492 | ||
492 | //parse the rest until no more parsing is possible | 493 | //parse the rest until no more parsing is possible |
493 | for(;;) { | 494 | for(;;) { |
494 | _state st(con); | 495 | _state st(con); |
495 | if (!m_expr->parse_non_term(con)) { | 496 | if (!m_expr->parse_non_term(con)) { |
496 | con.restore(st); | 497 | con.restore(st); |
497 | break; | 498 | break; |
498 | } | 499 | } |
499 | } | 500 | } |
500 | 501 | ||
501 | return true; | 502 | return true; |
502 | } | 503 | } |
503 | 504 | ||
504 | //parse terminal | 505 | //parse terminal |
505 | virtual bool parse_term(_context &con) const { | 506 | virtual bool parse_term(_context& con) const { |
506 | //parse the first; if the first fails, stop | 507 | //parse the first; if the first fails, stop |
507 | if (!m_expr->parse_term(con)) return false; | 508 | if (!m_expr->parse_term(con)) return false; |
508 | 509 | ||
509 | //parse the rest until no more parsing is possible | 510 | //parse the rest until no more parsing is possible |
510 | for(;;) { | 511 | for(;;) { |
511 | _state st(con); | 512 | _state st(con); |
512 | if (!m_expr->parse_term(con)) { | 513 | if (!m_expr->parse_term(con)) { |
513 | con.restore(st); | 514 | con.restore(st); |
514 | break; | 515 | break; |
515 | } | 516 | } |
516 | } | 517 | } |
517 | 518 | ||
518 | return true; | 519 | return true; |
519 | } | 520 | } |
520 | }; | 521 | }; |
521 | 522 | ||
522 | 523 | ||
523 | //optional | 524 | //optional |
524 | class _optional : public _unary { | 525 | class _optional : public _unary { |
525 | public: | 526 | public: |
526 | //constructor. | 527 | //constructor. |
527 | _optional(_expr *e) : | 528 | _optional(_expr* e) : |
528 | _unary(e) | 529 | _unary(e) |
529 | { | 530 | { |
530 | } | 531 | } |
531 | 532 | ||
532 | //parse with whitespace | 533 | //parse with whitespace |
533 | virtual bool parse_non_term(_context &con) const { | 534 | virtual bool parse_non_term(_context& con) const { |
534 | _state st(con); | 535 | _state st(con); |
535 | if (!m_expr->parse_non_term(con)) con.restore(st); | 536 | if (!m_expr->parse_non_term(con)) con.restore(st); |
536 | return true; | 537 | return true; |
537 | } | 538 | } |
538 | 539 | ||
539 | //parse terminal | 540 | //parse terminal |
540 | virtual bool parse_term(_context &con) const { | 541 | virtual bool parse_term(_context& con) const { |
541 | _state st(con); | 542 | _state st(con); |
542 | if (!m_expr->parse_term(con)) con.restore(st); | 543 | if (!m_expr->parse_term(con)) con.restore(st); |
543 | return true; | 544 | return true; |
544 | } | 545 | } |
545 | }; | 546 | }; |
546 | 547 | ||
547 | 548 | ||
548 | //and | 549 | //and |
549 | class _and : public _unary { | 550 | class _and : public _unary { |
550 | public: | 551 | public: |
551 | //constructor. | 552 | //constructor. |
552 | _and(_expr *e) : | 553 | _and(_expr* e) : |
553 | _unary(e) | 554 | _unary(e) |
554 | { | 555 | { |
555 | } | 556 | } |
556 | 557 | ||
557 | //parse with whitespace | 558 | //parse with whitespace |
558 | virtual bool parse_non_term(_context &con) const { | 559 | virtual bool parse_non_term(_context& con) const { |
559 | _state st(con); | 560 | _state st(con); |
560 | bool ok = m_expr->parse_non_term(con); | 561 | bool ok = m_expr->parse_non_term(con); |
561 | con.restore(st); | 562 | con.restore(st); |
562 | return ok; | 563 | return ok; |
563 | } | 564 | } |
564 | 565 | ||
565 | //parse terminal | 566 | //parse terminal |
566 | virtual bool parse_term(_context &con) const { | 567 | virtual bool parse_term(_context& con) const { |
567 | _state st(con); | 568 | _state st(con); |
568 | bool ok = m_expr->parse_term(con); | 569 | bool ok = m_expr->parse_term(con); |
569 | con.restore(st); | 570 | con.restore(st); |
570 | return ok; | 571 | return ok; |
571 | } | 572 | } |
572 | }; | 573 | }; |
573 | 574 | ||
574 | 575 | ||
575 | //not | 576 | //not |
576 | class _not : public _unary { | 577 | class _not : public _unary { |
577 | public: | 578 | public: |
578 | //constructor. | 579 | //constructor. |
579 | _not(_expr *e) : | 580 | _not(_expr* e) : |
580 | _unary(e) | 581 | _unary(e) |
581 | { | 582 | { |
582 | } | 583 | } |
583 | 584 | ||
584 | //parse with whitespace | 585 | //parse with whitespace |
585 | virtual bool parse_non_term(_context &con) const { | 586 | virtual bool parse_non_term(_context& con) const { |
586 | _state st(con); | 587 | _state st(con); |
587 | bool ok = !m_expr->parse_non_term(con); | 588 | bool ok = !m_expr->parse_non_term(con); |
588 | con.restore(st); | 589 | con.restore(st); |
589 | return ok; | 590 | return ok; |
590 | } | 591 | } |
591 | 592 | ||
592 | //parse terminal | 593 | //parse terminal |
593 | virtual bool parse_term(_context &con) const { | 594 | virtual bool parse_term(_context& con) const { |
594 | _state st(con); | 595 | _state st(con); |
595 | bool ok = !m_expr->parse_term(con); | 596 | bool ok = !m_expr->parse_term(con); |
596 | con.restore(st); | 597 | con.restore(st); |
597 | return ok; | 598 | return ok; |
598 | } | 599 | } |
599 | }; | 600 | }; |
600 | 601 | ||
601 | 602 | ||
602 | //newline | 603 | //newline |
603 | class _nl : public _unary { | 604 | class _nl : public _unary { |
604 | public: | 605 | public: |
605 | //constructor. | 606 | //constructor. |
606 | _nl(_expr *e) : | 607 | _nl(_expr* e) : |
607 | _unary(e) | 608 | _unary(e) |
608 | { | 609 | { |
609 | } | 610 | } |
610 | 611 | ||
611 | //parse with whitespace | 612 | //parse with whitespace |
612 | virtual bool parse_non_term(_context &con) const { | 613 | virtual bool parse_non_term(_context& con) const { |
613 | if (!m_expr->parse_non_term(con)) return false; | 614 | if (!m_expr->parse_non_term(con)) return false; |
614 | con.next_line(); | 615 | con.next_line(); |
615 | return true; | 616 | return true; |
616 | } | 617 | } |
617 | 618 | ||
618 | //parse terminal | 619 | //parse terminal |
619 | virtual bool parse_term(_context &con) const { | 620 | virtual bool parse_term(_context& con) const { |
620 | if (!m_expr->parse_term(con)) return false; | 621 | if (!m_expr->parse_term(con)) return false; |
621 | con.next_line(); | 622 | con.next_line(); |
622 | return true; | 623 | return true; |
623 | } | 624 | } |
624 | }; | 625 | }; |
625 | 626 | ||
626 | 627 | ||
627 | //base class for binary expressions | 628 | //base class for binary expressions |
628 | class _binary : public _expr { | 629 | class _binary : public _expr { |
629 | public: | 630 | public: |
630 | //constructor. | 631 | //constructor. |
631 | _binary(_expr *left, _expr *right) : | 632 | _binary(_expr* left, _expr* right) : |
632 | m_left(left), m_right(right) | 633 | m_left(left), m_right(right) |
633 | { | 634 | { |
634 | } | 635 | } |
635 | 636 | ||
636 | //destructor. | 637 | //destructor. |
637 | virtual ~_binary() { | 638 | virtual ~_binary() { |
638 | delete m_left; | 639 | delete m_left; |
639 | delete m_right; | 640 | delete m_right; |
640 | } | 641 | } |
641 | 642 | ||
642 | protected: | 643 | protected: |
643 | //left and right expressions | 644 | //left and right expressions |
644 | _expr *m_left, *m_right; | 645 | _expr* m_left, *m_right; |
645 | }; | 646 | }; |
646 | 647 | ||
647 | 648 | ||
648 | //sequence | 649 | //sequence |
649 | class _seq : public _binary { | 650 | class _seq : public _binary { |
650 | public: | 651 | public: |
651 | //constructor. | 652 | //constructor. |
652 | _seq(_expr *left, _expr *right) : | 653 | _seq(_expr* left, _expr* right) : |
653 | _binary(left, right) | 654 | _binary(left, right) |
654 | { | 655 | { |
655 | } | 656 | } |
656 | 657 | ||
657 | //parse with whitespace | 658 | //parse with whitespace |
658 | virtual bool parse_non_term(_context &con) const { | 659 | virtual bool parse_non_term(_context& con) const { |
659 | if (!m_left->parse_non_term(con)) return false; | 660 | if (!m_left->parse_non_term(con)) return false; |
660 | return m_right->parse_non_term(con); | 661 | return m_right->parse_non_term(con); |
661 | } | 662 | } |
662 | 663 | ||
663 | //parse terminal | 664 | //parse terminal |
664 | virtual bool parse_term(_context &con) const { | 665 | virtual bool parse_term(_context& con) const { |
665 | if (!m_left->parse_term(con)) return false; | 666 | if (!m_left->parse_term(con)) return false; |
666 | return m_right->parse_term(con); | 667 | return m_right->parse_term(con); |
667 | } | 668 | } |
668 | }; | 669 | }; |
669 | 670 | ||
670 | 671 | ||
671 | //choice | 672 | //choice |
672 | class _choice : public _binary { | 673 | class _choice : public _binary { |
673 | public: | 674 | public: |
674 | //constructor. | 675 | //constructor. |
675 | _choice(_expr *left, _expr *right) : | 676 | _choice(_expr* left, _expr* right) : |
676 | _binary(left, right) | 677 | _binary(left, right) |
677 | { | 678 | { |
678 | } | 679 | } |
679 | 680 | ||
680 | //parse with whitespace | 681 | //parse with whitespace |
681 | virtual bool parse_non_term(_context &con) const { | 682 | virtual bool parse_non_term(_context& con) const { |
682 | _state st(con); | 683 | _state st(con); |
683 | if (m_left->parse_non_term(con)) return true; | 684 | if (m_left->parse_non_term(con)) return true; |
684 | con.restore(st); | 685 | con.restore(st); |
685 | return m_right->parse_non_term(con); | 686 | return m_right->parse_non_term(con); |
686 | } | 687 | } |
687 | 688 | ||
688 | //parse terminal | 689 | //parse terminal |
689 | virtual bool parse_term(_context &con) const { | 690 | virtual bool parse_term(_context& con) const { |
690 | _state st(con); | 691 | _state st(con); |
691 | if (m_left->parse_term(con)) return true; | 692 | if (m_left->parse_term(con)) return true; |
692 | con.restore(st); | 693 | con.restore(st); |
693 | return m_right->parse_term(con); | 694 | return m_right->parse_term(con); |
694 | } | 695 | } |
695 | }; | 696 | }; |
696 | 697 | ||
697 | 698 | ||
698 | //reference to rule | 699 | //reference to rule |
699 | class _ref : public _expr { | 700 | class _ref : public _expr { |
700 | public: | 701 | public: |
701 | //constructor. | 702 | //constructor. |
702 | _ref(rule &r) : | 703 | _ref(rule& r) : |
703 | m_rule(r) | 704 | m_rule(r) |
704 | { | 705 | { |
705 | } | 706 | } |
706 | 707 | ||
707 | //parse with whitespace | 708 | //parse with whitespace |
708 | virtual bool parse_non_term(_context &con) const { | 709 | virtual bool parse_non_term(_context& con) const { |
709 | return con.parse_non_term(m_rule); | 710 | return con.parse_non_term(m_rule); |
710 | } | 711 | } |
711 | 712 | ||
712 | //parse terminal | 713 | //parse terminal |
713 | virtual bool parse_term(_context &con) const { | 714 | virtual bool parse_term(_context& con) const { |
714 | return con.parse_term(m_rule); | 715 | return con.parse_term(m_rule); |
715 | } | 716 | } |
716 | 717 | ||
717 | private: | 718 | private: |
718 | //reference | 719 | //reference |
719 | rule &m_rule; | 720 | rule &m_rule; |
720 | }; | 721 | }; |
721 | 722 | ||
722 | 723 | ||
723 | //eof | 724 | //eof |
724 | class _eof : public _expr { | 725 | class _eof : public _expr { |
725 | public: | 726 | public: |
726 | //parse with whitespace | 727 | //parse with whitespace |
727 | virtual bool parse_non_term(_context &con) const { | 728 | virtual bool parse_non_term(_context& con) const { |
728 | return parse_term(con); | 729 | return parse_term(con); |
729 | } | 730 | } |
730 | 731 | ||
731 | //parse terminal | 732 | //parse terminal |
732 | virtual bool parse_term(_context &con) const { | 733 | virtual bool parse_term(_context& con) const { |
733 | return con.end(); | 734 | return con.end(); |
734 | } | 735 | } |
735 | }; | 736 | }; |
736 | 737 | ||
737 | 738 | ||
738 | //any | 739 | //any |
739 | class _any : public _expr { | 740 | class _any : public _expr { |
740 | public: | 741 | public: |
741 | //parse with whitespace | 742 | //parse with whitespace |
742 | virtual bool parse_non_term(_context &con) const { | 743 | virtual bool parse_non_term(_context& con) const { |
743 | return parse_term(con); | 744 | return parse_term(con); |
744 | } | 745 | } |
745 | 746 | ||
746 | //parse terminal | 747 | //parse terminal |
747 | virtual bool parse_term(_context &con) const { | 748 | virtual bool parse_term(_context& con) const { |
748 | if (!con.end()) { | 749 | if (!con.end()) { |
749 | con.next_col(); | 750 | con.next_col(); |
750 | return true; | 751 | return true; |
751 | } | 752 | } |
752 | con.set_error_pos(); | 753 | con.set_error_pos(); |
753 | return false; | 754 | return false; |
754 | } | 755 | } |
755 | }; | 756 | }; |
756 | 757 | ||
757 | 758 | ||
@@ -759,12 +760,12 @@ public: | |||
759 | class _true : public _expr { | 760 | class _true : public _expr { |
760 | public: | 761 | public: |
761 | //parse with whitespace | 762 | //parse with whitespace |
762 | virtual bool parse_non_term(_context &) const { | 763 | virtual bool parse_non_term(_context&) const { |
763 | return true; | 764 | return true; |
764 | } | 765 | } |
765 | 766 | ||
766 | //parse terminal | 767 | //parse terminal |
767 | virtual bool parse_term(_context &) const { | 768 | virtual bool parse_term(_context&) const { |
768 | return true; | 769 | return true; |
769 | } | 770 | } |
770 | }; | 771 | }; |
@@ -774,600 +775,588 @@ public: | |||
774 | class _false: public _expr { | 775 | class _false: public _expr { |
775 | public: | 776 | public: |
776 | //parse with whitespace | 777 | //parse with whitespace |
777 | virtual bool parse_non_term(_context &) const { | 778 | virtual bool parse_non_term(_context&) const { |
778 | return false; | 779 | return false; |
779 | } | 780 | } |
780 | 781 | ||
781 | //parse terminal | 782 | //parse terminal |
782 | virtual bool parse_term(_context &) const { | 783 | virtual bool parse_term(_context&) const { |
783 | return false; | 784 | return false; |
784 | } | 785 | } |
785 | }; | 786 | }; |
786 | 787 | ||
787 | //exception thrown when left recursion terminates successfully | 788 | //exception thrown when left recursion terminates successfully |
788 | struct _lr_ok { | 789 | struct _lr_ok { |
789 | rule *m_rule; | 790 | rule* m_rule; |
790 | _lr_ok(rule *r) : m_rule(r) {} | 791 | _lr_ok(rule* r) : m_rule(r) {} |
791 | }; | 792 | }; |
792 | 793 | ||
793 | 794 | ||
794 | //constructor | 795 | //constructor |
795 | _state::_state(_context &con) : | 796 | _state::_state(_context& con) : |
796 | m_pos(con.m_pos), | 797 | m_pos(con.m_pos), |
797 | m_matches(con.m_matches.size()) | 798 | m_matches(con.m_matches.size()) |
798 | { | 799 | { |
799 | } | 800 | } |
800 | 801 | ||
801 | 802 | ||
802 | //parse non-term rule. | 803 | //parse non-term rule. |
803 | bool _context::parse_non_term(rule &r) { | 804 | bool _context::parse_non_term(rule& r) { |
804 | //save the state of the rule | 805 | //save the state of the rule |
805 | rule::_state old_state = r.m_state; | 806 | rule::_state old_state = r.m_state; |
806 | 807 | ||
807 | //success/failure result | 808 | //success/failure result |
808 | bool ok = false; | 809 | bool ok = false; |
809 | 810 | ||
810 | //compute the new position | 811 | //compute the new position |
811 | size_t new_pos = m_pos.m_it - m_begin; | 812 | size_t new_pos = m_pos.m_it - m_begin; |
812 | 813 | ||
813 | //check if we have left recursion | 814 | //check if we have left recursion |
814 | bool lr = new_pos == r.m_state.m_pos; | 815 | bool lr = new_pos == r.m_state.m_pos; |
815 | 816 | ||
816 | //update the rule's state | 817 | //update the rule's state |
817 | r.m_state.m_pos = new_pos; | 818 | r.m_state.m_pos = new_pos; |
818 | 819 | ||
819 | //handle the mode of the rule | 820 | //handle the mode of the rule |
820 | switch (r.m_state.m_mode) { | 821 | switch (r.m_state.m_mode) { |
821 | //normal parse | 822 | //normal parse |
822 | case rule::_PARSE: | 823 | case rule::_PARSE: |
823 | if (lr) { | 824 | if (lr) { |
824 | //first try to parse the rule by rejecting it, so alternative branches are examined | 825 | //first try to parse the rule by rejecting it, so alternative branches are examined |
825 | r.m_state.m_mode = rule::_REJECT; | 826 | r.m_state.m_mode = rule::_REJECT; |
826 | ok = _parse_non_term(r); | 827 | ok = _parse_non_term(r); |
827 | 828 | ||
828 | //if the first try is successful, try accepting the rule, | 829 | //if the first try is successful, try accepting the rule, |
829 | //so other elements of the sequence are parsed | 830 | //so other elements of the sequence are parsed |
830 | if (ok) { | 831 | if (ok) { |
831 | r.m_state.m_mode = rule::_ACCEPT; | 832 | r.m_state.m_mode = rule::_ACCEPT; |
832 | 833 | ||
833 | //loop until no more parsing can be done | 834 | //loop until no more parsing can be done |
834 | for(;;) { | 835 | for(;;) { |
835 | //store the correct state, in order to backtrack if the call fails | 836 | //store the correct state, in order to backtrack if the call fails |
836 | _state st(*this); | 837 | _state st(*this); |
837 | 838 | ||
838 | //update the rule position to the current position, | 839 | //update the rule position to the current position, |
839 | //because at this state the rule is resolving the left recursion | 840 | //because at this state the rule is resolving the left recursion |
840 | r.m_state.m_pos = m_pos.m_it - m_begin; | 841 | r.m_state.m_pos = m_pos.m_it - m_begin; |
841 | 842 | ||
842 | //if parsing fails, restore the last good state and stop | 843 | //if parsing fails, restore the last good state and stop |
843 | if (!_parse_non_term(r)) { | 844 | if (!_parse_non_term(r)) { |
844 | restore(st); | 845 | restore(st); |
845 | break; | 846 | break; |
846 | } | 847 | } |
847 | } | 848 | } |
848 | 849 | ||
849 | //since the left recursion was resolved successfully, | 850 | //since the left recursion was resolved successfully, |
850 | //return via a non-local exit | 851 | //return via a non-local exit |
851 | r.m_state = old_state; | 852 | r.m_state = old_state; |
852 | throw _lr_ok(r.this_ptr()); | 853 | throw _lr_ok(r.this_ptr()); |
853 | } | 854 | } |
854 | } | 855 | } |
855 | else { | 856 | else { |
856 | try { | 857 | try { |
857 | ok = _parse_non_term(r); | 858 | ok = _parse_non_term(r); |
858 | } | 859 | } |
859 | catch (const _lr_ok &ex) { | 860 | catch (const _lr_ok &ex) { |
860 | //since left recursions may be mutual, we must test which rule's left recursion | 861 | //since left recursions may be mutual, we must test which rule's left recursion |
861 | //was ended successfully | 862 | //was ended successfully |
862 | if (ex.m_rule == r.this_ptr()) { | 863 | if (ex.m_rule == r.this_ptr()) { |
863 | ok = true; | 864 | ok = true; |
864 | } | 865 | } |
865 | else { | 866 | else { |
866 | r.m_state = old_state; | 867 | r.m_state = old_state; |
867 | throw; | 868 | throw; |
868 | } | 869 | } |
869 | } | 870 | } |
870 | } | 871 | } |
871 | break; | 872 | break; |
872 | 873 | ||
873 | //reject the left recursive rule | 874 | //reject the left recursive rule |
874 | case rule::_REJECT: | 875 | case rule::_REJECT: |
875 | if (lr) { | 876 | if (lr) { |
876 | ok = false; | 877 | ok = false; |
877 | } | 878 | } |
878 | else { | 879 | else { |
879 | r.m_state.m_mode = rule::_PARSE; | 880 | r.m_state.m_mode = rule::_PARSE; |
880 | ok = _parse_non_term(r); | 881 | ok = _parse_non_term(r); |
881 | r.m_state.m_mode = rule::_REJECT; | 882 | r.m_state.m_mode = rule::_REJECT; |
882 | } | 883 | } |
883 | break; | 884 | break; |
884 | 885 | ||
885 | //accept the left recursive rule | 886 | //accept the left recursive rule |
886 | case rule::_ACCEPT: | 887 | case rule::_ACCEPT: |
887 | if (lr) { | 888 | if (lr) { |
888 | ok = true; | 889 | ok = true; |
889 | } | 890 | } |
890 | else { | 891 | else { |
891 | r.m_state.m_mode = rule::_PARSE; | 892 | r.m_state.m_mode = rule::_PARSE; |
892 | ok = _parse_non_term(r); | 893 | ok = _parse_non_term(r); |
893 | r.m_state.m_mode = rule::_ACCEPT; | 894 | r.m_state.m_mode = rule::_ACCEPT; |
894 | } | 895 | } |
895 | break; | 896 | break; |
896 | } | 897 | } |
897 | 898 | ||
898 | //restore the rule's state | 899 | //restore the rule's state |
899 | r.m_state = old_state; | 900 | r.m_state = old_state; |
900 | 901 | ||
901 | return ok; | 902 | return ok; |
902 | } | 903 | } |
903 | 904 | ||
904 | 905 | ||
905 | //parse term rule. | 906 | //parse term rule. |
906 | bool _context::parse_term(rule &r) { | 907 | bool _context::parse_term(rule& r) { |
907 | //save the state of the rule | 908 | //save the state of the rule |
908 | rule::_state old_state = r.m_state; | 909 | rule::_state old_state = r.m_state; |
909 | 910 | ||
910 | //success/failure result | 911 | //success/failure result |
911 | bool ok = false; | 912 | bool ok = false; |
912 | 913 | ||
913 | //compute the new position | 914 | //compute the new position |
914 | size_t new_pos = m_pos.m_it - m_begin; | 915 | size_t new_pos = m_pos.m_it - m_begin; |
915 | 916 | ||
916 | //check if we have left recursion | 917 | //check if we have left recursion |
917 | bool lr = new_pos == r.m_state.m_pos; | 918 | bool lr = new_pos == r.m_state.m_pos; |
918 | 919 | ||
919 | //update the rule's state | 920 | //update the rule's state |
920 | r.m_state.m_pos = new_pos; | 921 | r.m_state.m_pos = new_pos; |
921 | 922 | ||
922 | //handle the mode of the rule | 923 | //handle the mode of the rule |
923 | switch (r.m_state.m_mode) { | 924 | switch (r.m_state.m_mode) { |
924 | //normal parse | 925 | //normal parse |
925 | case rule::_PARSE: | 926 | case rule::_PARSE: |
926 | if (lr) { | 927 | if (lr) { |
927 | //first try to parse the rule by rejecting it, so alternative branches are examined | 928 | //first try to parse the rule by rejecting it, so alternative branches are examined |
928 | r.m_state.m_mode = rule::_REJECT; | 929 | r.m_state.m_mode = rule::_REJECT; |
929 | ok = _parse_term(r); | 930 | ok = _parse_term(r); |
930 | 931 | ||
931 | //if the first try is successful, try accepting the rule, | 932 | //if the first try is successful, try accepting the rule, |
932 | //so other elements of the sequence are parsed | 933 | //so other elements of the sequence are parsed |
933 | if (ok) { | 934 | if (ok) { |
934 | r.m_state.m_mode = rule::_ACCEPT; | 935 | r.m_state.m_mode = rule::_ACCEPT; |
935 | 936 | ||
936 | //loop until no more parsing can be done | 937 | //loop until no more parsing can be done |
937 | for(;;) { | 938 | for(;;) { |
938 | //store the correct state, in order to backtrack if the call fails | 939 | //store the correct state, in order to backtrack if the call fails |
939 | _state st(*this); | 940 | _state st(*this); |
940 | 941 | ||
941 | //update the rule position to the current position, | 942 | //update the rule position to the current position, |
942 | //because at this state the rule is resolving the left recursion | 943 | //because at this state the rule is resolving the left recursion |
943 | r.m_state.m_pos = m_pos.m_it - m_begin; | 944 | r.m_state.m_pos = m_pos.m_it - m_begin; |
944 | 945 | ||
945 | //if parsing fails, restore the last good state and stop | 946 | //if parsing fails, restore the last good state and stop |
946 | if (!_parse_term(r)) { | 947 | if (!_parse_term(r)) { |
947 | restore(st); | 948 | restore(st); |
948 | break; | 949 | break; |
949 | } | 950 | } |
950 | } | 951 | } |
951 | 952 | ||
952 | //since the left recursion was resolved successfully, | 953 | //since the left recursion was resolved successfully, |
953 | //return via a non-local exit | 954 | //return via a non-local exit |
954 | r.m_state = old_state; | 955 | r.m_state = old_state; |
955 | throw _lr_ok(r.this_ptr()); | 956 | throw _lr_ok(r.this_ptr()); |
956 | } | 957 | } |
957 | } | 958 | } |
958 | else { | 959 | else { |
959 | try { | 960 | try { |
960 | ok = _parse_term(r); | 961 | ok = _parse_term(r); |
961 | } | 962 | } |
962 | catch (const _lr_ok &ex) { | 963 | catch (const _lr_ok& ex) { |
963 | //since left recursions may be mutual, we must test which rule's left recursion | 964 | //since left recursions may be mutual, we must test which rule's left recursion |
964 | //was ended successfully | 965 | //was ended successfully |
965 | if (ex.m_rule == r.this_ptr()) { | 966 | if (ex.m_rule == r.this_ptr()) { |
966 | ok = true; | 967 | ok = true; |
967 | } | 968 | } |
968 | else { | 969 | else { |
969 | r.m_state = old_state; | 970 | r.m_state = old_state; |
970 | throw; | 971 | throw; |
971 | } | 972 | } |
972 | } | 973 | } |
973 | } | 974 | } |
974 | break; | 975 | break; |
975 | 976 | ||
976 | //reject the left recursive rule | 977 | //reject the left recursive rule |
977 | case rule::_REJECT: | 978 | case rule::_REJECT: |
978 | if (lr) { | 979 | if (lr) { |
979 | ok = false; | 980 | ok = false; |
980 | } | 981 | } |
981 | else { | 982 | else { |
982 | r.m_state.m_mode = rule::_PARSE; | 983 | r.m_state.m_mode = rule::_PARSE; |
983 | ok = _parse_term(r); | 984 | ok = _parse_term(r); |
984 | r.m_state.m_mode = rule::_REJECT; | 985 | r.m_state.m_mode = rule::_REJECT; |
985 | } | 986 | } |
986 | break; | 987 | break; |
987 | 988 | ||
988 | //accept the left recursive rule | 989 | //accept the left recursive rule |
989 | case rule::_ACCEPT: | 990 | case rule::_ACCEPT: |
990 | if (lr) { | 991 | if (lr) { |
991 | ok = true; | 992 | ok = true; |
992 | } | 993 | } |
993 | else { | 994 | else { |
994 | r.m_state.m_mode = rule::_PARSE; | 995 | r.m_state.m_mode = rule::_PARSE; |
995 | ok = _parse_term(r); | 996 | ok = _parse_term(r); |
996 | r.m_state.m_mode = rule::_ACCEPT; | 997 | r.m_state.m_mode = rule::_ACCEPT; |
997 | } | 998 | } |
998 | break; | 999 | break; |
999 | } | 1000 | } |
1000 | 1001 | ||
1001 | //restore the rule's state | 1002 | //restore the rule's state |
1002 | r.m_state = old_state; | 1003 | r.m_state = old_state; |
1003 | 1004 | ||
1004 | return ok; | 1005 | return ok; |
1005 | } | 1006 | } |
1006 | 1007 | ||
1007 | 1008 | ||
1008 | //parse non-term rule internal. | 1009 | //parse non-term rule internal. |
1009 | bool _context::_parse_non_term(rule &r) { | 1010 | bool _context::_parse_non_term(rule& r) { |
1010 | bool ok = false; | 1011 | bool ok = false; |
1011 | if (_private::get_parse_proc(r)) { | 1012 | if (_private::get_parse_proc(r)) { |
1012 | pos b = m_pos; | 1013 | pos b = m_pos; |
1013 | ok = _private::get_expr(r)->parse_non_term(*this); | 1014 | ok = _private::get_expr(r)->parse_non_term(*this); |
1014 | if (ok) { | 1015 | if (ok) { |
1015 | m_matches.push_back(_match(r.this_ptr(), b, m_pos)); | 1016 | m_matches.push_back(_match(r.this_ptr(), b, m_pos)); |
1016 | } | 1017 | } |
1017 | } | 1018 | } |
1018 | else { | 1019 | else { |
1019 | ok = _private::get_expr(r)->parse_non_term(*this); | 1020 | ok = _private::get_expr(r)->parse_non_term(*this); |
1020 | } | 1021 | } |
1021 | return ok; | 1022 | return ok; |
1022 | } | 1023 | } |
1023 | 1024 | ||
1024 | 1025 | ||
1025 | //parse term rule internal. | 1026 | //parse term rule internal. |
1026 | bool _context::_parse_term(rule &r) { | 1027 | bool _context::_parse_term(rule& r) { |
1027 | bool ok = false; | 1028 | bool ok = false; |
1028 | if (_private::get_parse_proc(r)) { | 1029 | if (_private::get_parse_proc(r)) { |
1029 | pos b = m_pos; | 1030 | pos b = m_pos; |
1030 | ok = _private::get_expr(r)->parse_term(*this); | 1031 | ok = _private::get_expr(r)->parse_term(*this); |
1031 | if (ok) { | 1032 | if (ok) { |
1032 | m_matches.push_back(_match(r.this_ptr(), b, m_pos)); | 1033 | m_matches.push_back(_match(r.this_ptr(), b, m_pos)); |
1033 | } | 1034 | } |
1034 | } | 1035 | } |
1035 | else { | 1036 | else { |
1036 | ok = _private::get_expr(r)->parse_term(*this); | 1037 | ok = _private::get_expr(r)->parse_term(*this); |
1037 | } | 1038 | } |
1038 | return ok; | 1039 | return ok; |
1039 | } | 1040 | } |
1040 | 1041 | ||
1041 | 1042 | ||
1042 | //get syntax error | 1043 | //get syntax error |
1043 | static error _syntax_error(_context &con) { | 1044 | static error _syntax_error(_context& con) { |
1044 | return error(con.m_error_pos, con.m_error_pos, ERROR_SYNTAX_ERROR); | 1045 | return error(con.m_error_pos, con.m_error_pos, ERROR_SYNTAX_ERROR); |
1045 | } | 1046 | } |
1046 | 1047 | ||
1047 | 1048 | ||
1048 | //get eof error | 1049 | //get eof error |
1049 | static error _eof_error(_context &con) { | 1050 | static error _eof_error(_context& con) { |
1050 | return error(con.m_error_pos, con.m_error_pos, ERROR_INVALID_EOF); | 1051 | return error(con.m_error_pos, con.m_error_pos, ERROR_INVALID_EOF); |
1051 | } | 1052 | } |
1052 | 1053 | ||
1053 | 1054 | ||
1054 | /** constructor from input. | 1055 | /** constructor from input. |
1055 | @param i input. | 1056 | @param i input. |
1056 | */ | 1057 | */ |
1057 | pos::pos(input &i) : | 1058 | pos::pos(input& i) : |
1058 | m_it(i.begin()), | 1059 | m_it(i.begin()), |
1059 | m_line(1), | 1060 | m_line(1), |
1060 | m_col(1) | 1061 | m_col(1) |
1061 | { | 1062 | { |
1062 | } | 1063 | } |
1063 | 1064 | ||
1064 | 1065 | ||
1065 | /** character terminal constructor. | 1066 | /** character terminal constructor. |
1066 | @param c character. | 1067 | @param c character. |
1067 | */ | 1068 | */ |
1068 | expr::expr(char c) : | 1069 | expr::expr(char c) : |
1069 | m_expr(new _char(c)) | 1070 | m_expr(new _char(c)) |
1070 | { | 1071 | { |
1071 | } | 1072 | } |
1072 | 1073 | ||
1073 | 1074 | ||
1074 | /** null-terminated string terminal constructor. | 1075 | /** null-terminated string terminal constructor. |
1075 | @param s null-terminated string. | 1076 | @param s null-terminated string. |
1076 | */ | 1077 | */ |
1077 | expr::expr(const char *s) : | 1078 | expr::expr(const char* s) : |
1078 | m_expr(new _string(s)) | 1079 | m_expr(new _string(s)) |
1079 | { | 1080 | { |
1080 | } | 1081 | } |
1081 | 1082 | ||
1082 | 1083 | ||
1083 | /** rule reference constructor. | 1084 | /** rule reference constructor. |
1084 | @param r rule. | 1085 | @param r rule. |
1085 | */ | 1086 | */ |
1086 | expr::expr(rule &r) : | 1087 | expr::expr(rule& r) : |
1087 | m_expr(new _ref(r)) | 1088 | m_expr(new _ref(r)) |
1088 | { | 1089 | { |
1089 | } | 1090 | } |
1090 | 1091 | ||
1091 | 1092 | ||
1092 | /** creates a zero-or-more loop out of this expression. | 1093 | /** creates a zero-or-more loop out of this expression. |
1093 | @return a zero-or-more loop expression. | 1094 | @return a zero-or-more loop expression. |
1094 | */ | 1095 | */ |
1095 | expr expr::operator *() const { | 1096 | expr expr::operator*() const { |
1096 | return _private::construct_expr(new _loop0(m_expr)); | 1097 | return _private::construct_expr(new _loop0(m_expr)); |
1097 | } | 1098 | } |
1098 | 1099 | ||
1099 | 1100 | ||
1100 | /** creates a one-or-more loop out of this expression. | 1101 | /** creates a one-or-more loop out of this expression. |
1101 | @return a one-or-more loop expression. | 1102 | @return a one-or-more loop expression. |
1102 | */ | 1103 | */ |
1103 | expr expr::operator +() const { | 1104 | expr expr::operator+() const { |
1104 | return _private::construct_expr(new _loop1(m_expr)); | 1105 | return _private::construct_expr(new _loop1(m_expr)); |
1105 | } | 1106 | } |
1106 | 1107 | ||
1107 | 1108 | ||
1108 | /** creates an optional out of this expression. | 1109 | /** creates an optional out of this expression. |
1109 | @return an optional expression. | 1110 | @return an optional expression. |
1110 | */ | 1111 | */ |
1111 | expr expr::operator -() const { | 1112 | expr expr::operator-() const { |
1112 | return _private::construct_expr(new _optional(m_expr)); | 1113 | return _private::construct_expr(new _optional(m_expr)); |
1113 | } | 1114 | } |
1114 | 1115 | ||
1115 | 1116 | ||
1116 | /** creates an AND-expression. | 1117 | /** creates an AND-expression. |
1117 | @return an AND-expression. | 1118 | @return an AND-expression. |
1118 | */ | 1119 | */ |
1119 | expr expr::operator &() const { | 1120 | expr expr::operator&() const { |
1120 | return _private::construct_expr((new _and(m_expr))); | 1121 | return _private::construct_expr((new _and(m_expr))); |
1121 | } | 1122 | } |
1122 | 1123 | ||
1123 | 1124 | ||
1124 | /** creates a NOT-expression. | 1125 | /** creates a NOT-expression. |
1125 | @return a NOT-expression. | 1126 | @return a NOT-expression. |
1126 | */ | 1127 | */ |
1127 | expr expr::operator !() const { | 1128 | expr expr::operator!() const { |
1128 | return _private::construct_expr(new _not(m_expr)); | 1129 | return _private::construct_expr(new _not(m_expr)); |
1129 | } | 1130 | } |
1130 | 1131 | ||
1131 | 1132 | ||
1132 | /** constructor. | 1133 | /** constructor. |
1133 | @param b begin position. | 1134 | @param b begin position. |
1134 | @param e end position. | 1135 | @param e end position. |
1135 | */ | 1136 | */ |
1136 | input_range::input_range(const pos &b, const pos &e) : | 1137 | input_range::input_range(const pos& b, const pos& e) : |
1137 | m_begin(b), | 1138 | m_begin(b), |
1138 | m_end(e) {} | 1139 | m_end(e) {} |
1139 | 1140 | ||
1140 | 1141 | ||
1141 | /** constructor. | 1142 | /** constructor. |
1142 | @param b begin position. | 1143 | @param b begin position. |
1143 | @param e end position. | 1144 | @param e end position. |
1144 | @param t error type. | 1145 | @param t error type. |
1145 | */ | 1146 | */ |
1146 | error::error(const pos &b, const pos &e, int t) : | 1147 | error::error(const pos& b, const pos& e, int t) : |
1147 | input_range(b, e), | 1148 | input_range(b, e), |
1148 | m_type(t) {} | 1149 | m_type(t) {} |
1149 | 1150 | ||
1150 | 1151 | ||
1151 | /** compare on begin position. | 1152 | /** compare on begin position. |
1152 | @param e the other error to compare this with. | 1153 | @param e the other error to compare this with. |
1153 | @return true if this comes before the previous error, false otherwise. | 1154 | @return true if this comes before the previous error, false otherwise. |
1154 | */ | 1155 | */ |
1155 | bool error::operator < (const error &e) const { | 1156 | bool error::operator<(const error& e) const { |
1156 | return m_begin.m_it < e.m_begin.m_it; | 1157 | return m_begin.m_it < e.m_begin.m_it; |
1157 | } | 1158 | } |
1158 | 1159 | ||
1159 | rule::rule() : | 1160 | rule::rule() : |
1160 | m_expr(nullptr), | 1161 | m_expr(nullptr), |
1161 | m_parse_proc(nullptr) | 1162 | m_parse_proc(nullptr) {} |
1162 | { | ||
1163 | } | ||
1164 | 1163 | ||
1165 | /** character terminal constructor. | 1164 | /** character terminal constructor. |
1166 | @param c character. | 1165 | @param c character. |
1167 | */ | 1166 | */ |
1168 | rule::rule(char c) : | 1167 | rule::rule(char c) : |
1169 | m_expr(new _char(c)), | 1168 | m_expr(new _char(c)), |
1170 | m_parse_proc(nullptr) | 1169 | m_parse_proc(nullptr) {} |
1171 | { | ||
1172 | } | ||
1173 | |||
1174 | 1170 | ||
1175 | /** null-terminated string terminal constructor. | 1171 | /** null-terminated string terminal constructor. |
1176 | @param s null-terminated string. | 1172 | @param s null-terminated string. |
1177 | */ | 1173 | */ |
1178 | rule::rule(const char *s) : | 1174 | rule::rule(const char* s) : |
1179 | m_expr(new _string(s)), | 1175 | m_expr(new _string(s)), |
1180 | m_parse_proc(nullptr) | 1176 | m_parse_proc(nullptr) {} |
1181 | { | ||
1182 | } | ||
1183 | |||
1184 | 1177 | ||
1185 | /** constructor from expression. | 1178 | /** constructor from expression. |
1186 | @param e expression. | 1179 | @param e expression. |
1187 | */ | 1180 | */ |
1188 | rule::rule(const expr &e) : | 1181 | rule::rule(const expr& e) : |
1189 | m_expr(_private::get_expr(e)), | 1182 | m_expr(_private::get_expr(e)), |
1190 | m_parse_proc(nullptr) | 1183 | m_parse_proc(nullptr) {} |
1191 | { | ||
1192 | } | ||
1193 | 1184 | ||
1194 | 1185 | ||
1195 | /** constructor from rule. | 1186 | /** constructor from rule. |
1196 | @param r rule. | 1187 | @param r rule. |
1197 | */ | 1188 | */ |
1198 | rule::rule(rule &r) : | 1189 | rule::rule(rule& r) : |
1199 | m_expr(new _ref(r)), | 1190 | m_expr(new _ref(r)), |
1200 | m_parse_proc(nullptr) | 1191 | m_parse_proc(nullptr) {} |
1201 | { | ||
1202 | } | ||
1203 | 1192 | ||
1204 | rule& rule::operator = (rule & r) { | 1193 | rule& rule::operator=(rule& r) { |
1205 | m_expr = new _ref(r); | 1194 | m_expr = new _ref(r); |
1206 | return *this; | 1195 | return *this; |
1207 | } | 1196 | } |
1208 | 1197 | ||
1209 | rule &rule::operator = (const expr & e) { | 1198 | rule &rule::operator=(const expr& e) { |
1210 | m_expr = _private::get_expr(e); | 1199 | m_expr = _private::get_expr(e); |
1211 | return *this; | 1200 | return *this; |
1212 | } | 1201 | } |
1213 | 1202 | ||
1214 | /** invalid constructor from rule (required by gcc). | 1203 | /** invalid constructor from rule (required by gcc). |
1215 | @exception std::logic_error always thrown. | 1204 | @exception std::logic_error always thrown. |
1216 | */ | 1205 | */ |
1217 | rule::rule(const rule &) { | 1206 | rule::rule(const rule&) { |
1218 | throw std::logic_error("invalid operation"); | 1207 | throw std::logic_error("invalid operation"); |
1219 | } | 1208 | } |
1220 | 1209 | ||
1221 | 1210 | ||
1222 | /** deletes the internal object that represents the expression. | 1211 | /** deletes the internal object that represents the expression. |
1223 | */ | 1212 | */ |
1224 | rule::~rule() { | 1213 | rule::~rule() { |
1225 | delete m_expr; | 1214 | delete m_expr; |
1226 | } | 1215 | } |
1227 | 1216 | ||
1228 | 1217 | ||
1229 | /** creates a zero-or-more loop out of this rule. | 1218 | /** creates a zero-or-more loop out of this rule. |
1230 | @return a zero-or-more loop rule. | 1219 | @return a zero-or-more loop rule. |
1231 | */ | 1220 | */ |
1232 | expr rule::operator *() { | 1221 | expr rule::operator*() { |
1233 | return _private::construct_expr(new _loop0(new _ref(*this))); | 1222 | return _private::construct_expr(new _loop0(new _ref(*this))); |
1234 | } | 1223 | } |
1235 | 1224 | ||
1236 | 1225 | ||
1237 | /** creates a one-or-more loop out of this rule. | 1226 | /** creates a one-or-more loop out of this rule. |
1238 | @return a one-or-more loop rule. | 1227 | @return a one-or-more loop rule. |
1239 | */ | 1228 | */ |
1240 | expr rule::operator +() { | 1229 | expr rule::operator+() { |
1241 | return _private::construct_expr(new _loop1(new _ref(*this))); | 1230 | return _private::construct_expr(new _loop1(new _ref(*this))); |
1242 | } | 1231 | } |
1243 | 1232 | ||
1244 | 1233 | ||
1245 | /** creates an optional out of this rule. | 1234 | /** creates an optional out of this rule. |
1246 | @return an optional rule. | 1235 | @return an optional rule. |
1247 | */ | 1236 | */ |
1248 | expr rule::operator -() { | 1237 | expr rule::operator-() { |
1249 | return _private::construct_expr(new _optional(new _ref(*this))); | 1238 | return _private::construct_expr(new _optional(new _ref(*this))); |
1250 | } | 1239 | } |
1251 | 1240 | ||
1252 | 1241 | ||
1253 | /** creates an AND-expression out of this rule. | 1242 | /** creates an AND-expression out of this rule. |
1254 | @return an AND-expression out of this rule. | 1243 | @return an AND-expression out of this rule. |
1255 | */ | 1244 | */ |
1256 | expr rule::operator &() { | 1245 | expr rule::operator&() { |
1257 | return _private::construct_expr(new _and(new _ref(*this))); | 1246 | return _private::construct_expr(new _and(new _ref(*this))); |
1258 | } | 1247 | } |
1259 | 1248 | ||
1260 | 1249 | ||
1261 | /** creates a NOT-expression out of this rule. | 1250 | /** creates a NOT-expression out of this rule. |
1262 | @return a NOT-expression out of this rule. | 1251 | @return a NOT-expression out of this rule. |
1263 | */ | 1252 | */ |
1264 | expr rule::operator !() { | 1253 | expr rule::operator!() { |
1265 | return _private::construct_expr(new _not(new _ref(*this))); | 1254 | return _private::construct_expr(new _not(new _ref(*this))); |
1266 | } | 1255 | } |
1267 | 1256 | ||
1268 | 1257 | ||
1269 | /** sets the parse procedure. | 1258 | /** sets the parse procedure. |
1270 | @param p procedure. | 1259 | @param p procedure. |
1271 | */ | 1260 | */ |
1272 | void rule::set_parse_proc(parse_proc p) { | 1261 | void rule::set_parse_proc(parse_proc p) { |
1273 | assert(p); | 1262 | assert(p); |
1274 | m_parse_proc = p; | 1263 | m_parse_proc = p; |
1275 | } | 1264 | } |
1276 | 1265 | ||
1277 | 1266 | ||
1278 | /** creates a sequence of expressions. | 1267 | /** creates a sequence of expressions. |
1279 | @param left left operand. | 1268 | @param left left operand. |
1280 | @param right right operand. | 1269 | @param right right operand. |
1281 | @return an expression which parses a sequence. | 1270 | @return an expression which parses a sequence. |
1282 | */ | 1271 | */ |
1283 | expr operator >> (const expr &left, const expr &right) { | 1272 | expr operator >> (const expr& left, const expr& right) { |
1284 | return _private::construct_expr( | 1273 | return _private::construct_expr( |
1285 | new _seq(_private::get_expr(left), _private::get_expr(right))); | 1274 | new _seq(_private::get_expr(left), _private::get_expr(right))); |
1286 | } | 1275 | } |
1287 | 1276 | ||
1288 | 1277 | ||
1289 | /** creates a choice of expressions. | 1278 | /** creates a choice of expressions. |
1290 | @param left left operand. | 1279 | @param left left operand. |
1291 | @param right right operand. | 1280 | @param right right operand. |
1292 | @return an expression which parses a choice. | 1281 | @return an expression which parses a choice. |
1293 | */ | 1282 | */ |
1294 | expr operator | (const expr &left, const expr &right) { | 1283 | expr operator | (const expr& left, const expr& right) { |
1295 | return _private::construct_expr( | 1284 | return _private::construct_expr( |
1296 | new _choice(_private::get_expr(left), _private::get_expr(right))); | 1285 | new _choice(_private::get_expr(left), _private::get_expr(right))); |
1297 | } | 1286 | } |
1298 | 1287 | ||
1299 | 1288 | ||
1300 | /** converts a parser expression into a terminal. | 1289 | /** converts a parser expression into a terminal. |
1301 | @param e expression. | 1290 | @param e expression. |
1302 | @return an expression which parses a terminal. | 1291 | @return an expression which parses a terminal. |
1303 | */ | 1292 | */ |
1304 | expr term(const expr &e) { | 1293 | expr term(const expr& e) { |
1305 | return _private::construct_expr( | 1294 | return _private::construct_expr( |
1306 | new _term(_private::get_expr(e))); | 1295 | new _term(_private::get_expr(e))); |
1307 | } | 1296 | } |
1308 | 1297 | ||
1309 | 1298 | ||
1310 | /** creates a set expression from a null-terminated string. | 1299 | /** creates a set expression from a null-terminated string. |
1311 | @param s null-terminated string with characters of the set. | 1300 | @param s null-terminated string with characters of the set. |
1312 | @return an expression which parses a single character out of a set. | 1301 | @return an expression which parses a single character out of a set. |
1313 | */ | 1302 | */ |
1314 | expr set(const char *s) { | 1303 | expr set(const char* s) { |
1315 | return _private::construct_expr(new _set(s)); | 1304 | return _private::construct_expr(new _set(s)); |
1316 | } | 1305 | } |
1317 | 1306 | ||
1318 | 1307 | ||
1319 | /** creates a range expression. | 1308 | /** creates a range expression. |
1320 | @param min min character. | 1309 | @param min min character. |
1321 | @param max max character. | 1310 | @param max max character. |
1322 | @return an expression which parses a single character out of range. | 1311 | @return an expression which parses a single character out of range. |
1323 | */ | 1312 | */ |
1324 | expr range(int min, int max) { | 1313 | expr range(int min, int max) { |
1325 | return _private::construct_expr(new _set(min, max)); | 1314 | return _private::construct_expr(new _set(min, max)); |
1326 | } | 1315 | } |
1327 | 1316 | ||
1328 | 1317 | ||
1329 | /** creates an expression which increments the line counter | 1318 | /** creates an expression which increments the line counter |
1330 | and resets the column counter when the given expression | 1319 | and resets the column counter when the given expression |
1331 | is parsed successfully; used for newline characters. | 1320 | is parsed successfully; used for newline characters. |
1332 | @param e expression to wrap into a newline parser. | 1321 | @param e expression to wrap into a newline parser. |
1333 | @return an expression that handles newlines. | 1322 | @return an expression that handles newlines. |
1334 | */ | 1323 | */ |
1335 | expr nl(const expr &e) { | 1324 | expr nl(const expr& e) { |
1336 | return _private::construct_expr(new _nl(_private::get_expr(e))); | 1325 | return _private::construct_expr(new _nl(_private::get_expr(e))); |
1337 | } | 1326 | } |
1338 | 1327 | ||
1339 | 1328 | ||
1340 | /** creates an expression which tests for the end of input. | 1329 | /** creates an expression which tests for the end of input. |
1341 | @return an expression that handles the end of input. | 1330 | @return an expression that handles the end of input. |
1342 | */ | 1331 | */ |
1343 | expr eof() { | 1332 | expr eof() { |
1344 | return _private::construct_expr(new _eof()); | 1333 | return _private::construct_expr(new _eof()); |
1345 | } | 1334 | } |
1346 | 1335 | ||
1347 | 1336 | ||
1348 | /** creates a not expression. | 1337 | /** creates a not expression. |
1349 | @param e expression. | 1338 | @param e expression. |
1350 | @return the appropriate expression. | 1339 | @return the appropriate expression. |
1351 | */ | 1340 | */ |
1352 | expr not_(const expr &e) { | 1341 | expr not_(const expr& e) { |
1353 | return !e; | 1342 | return !e; |
1354 | } | 1343 | } |
1355 | 1344 | ||
1356 | 1345 | ||
1357 | /** creates an and expression. | 1346 | /** creates an and expression. |
1358 | @param e expression. | 1347 | @param e expression. |
1359 | @return the appropriate expression. | 1348 | @return the appropriate expression. |
1360 | */ | 1349 | */ |
1361 | expr and_(const expr &e) { | 1350 | expr and_(const expr& e) { |
1362 | return &e; | 1351 | return &e; |
1363 | } | 1352 | } |
1364 | 1353 | ||
1365 | 1354 | ||
1366 | /** creates an expression that parses any character. | 1355 | /** creates an expression that parses any character. |
1367 | @return the appropriate expression. | 1356 | @return the appropriate expression. |
1368 | */ | 1357 | */ |
1369 | expr any() { | 1358 | expr any() { |
1370 | return _private::construct_expr(new _any()); | 1359 | return _private::construct_expr(new _any()); |
1371 | } | 1360 | } |
1372 | 1361 | ||
1373 | 1362 | ||
@@ -1387,44 +1376,44 @@ expr false_() { | |||
1387 | 1376 | ||
1388 | /** parse with target expression and let user handle result. | 1377 | /** parse with target expression and let user handle result. |
1389 | */ | 1378 | */ |
1390 | expr user(const expr &e, const user_handler& handler) { | 1379 | expr user(const expr& e, const user_handler& handler) { |
1391 | return _private::construct_expr(new _user(_private::get_expr(e), handler)); | 1380 | return _private::construct_expr(new _user(_private::get_expr(e), handler)); |
1392 | } | 1381 | } |
1393 | 1382 | ||
1394 | 1383 | ||
1395 | /** parses the given input. | 1384 | /** parses the given input. |
1396 | The parse procedures of each rule parsed are executed | 1385 | The parse procedures of each rule parsed are executed |
1397 | before this function returns, if parsing succeeds. | 1386 | before this function returns, if parsing succeeds. |
1398 | @param i input. | 1387 | @param i input. |
1399 | @param g root rule of grammar. | 1388 | @param g root rule of grammar. |
1400 | @param el list of errors. | 1389 | @param el list of errors. |
1401 | @param d user data, passed to the parse procedures. | 1390 | @param d user data, passed to the parse procedures. |
1402 | @return true on parsing success, false on failure. | 1391 | @return true on parsing success, false on failure. |
1403 | */ | 1392 | */ |
1404 | bool parse(input &i, rule &g, error_list &el, void *d, void* ud) { | 1393 | bool parse(input& i, rule& g, error_list& el, void* d, void* ud) { |
1405 | //prepare context | 1394 | //prepare context |
1406 | _context con(i, ud); | 1395 | _context con(i, ud); |
1407 | 1396 | ||
1408 | //parse grammar | 1397 | //parse grammar |
1409 | if (!con.parse_non_term(g)) { | 1398 | if (!con.parse_non_term(g)) { |
1410 | el.push_back(_syntax_error(con)); | 1399 | el.push_back(_syntax_error(con)); |
1411 | return false; | 1400 | return false; |
1412 | } | 1401 | } |
1413 | 1402 | ||
1414 | //if end is not reached, there was an error | 1403 | //if end is not reached, there was an error |
1415 | if (!con.end()) { | 1404 | if (!con.end()) { |
1416 | if (con.m_error_pos.m_it < con.m_end) { | 1405 | if (con.m_error_pos.m_it < con.m_end) { |
1417 | el.push_back(_syntax_error(con)); | 1406 | el.push_back(_syntax_error(con)); |
1418 | } | 1407 | } |
1419 | else { | 1408 | else { |
1420 | el.push_back(_eof_error(con)); | 1409 | el.push_back(_eof_error(con)); |
1421 | } | 1410 | } |
1422 | return false; | 1411 | return false; |
1423 | } | 1412 | } |
1424 | 1413 | ||
1425 | //success; execute the parse procedures | 1414 | //success; execute the parse procedures |
1426 | con.do_parse_procs(d); | 1415 | con.do_parse_procs(d); |
1427 | return true; | 1416 | return true; |
1428 | } | 1417 | } |
1429 | 1418 | ||
1430 | 1419 | ||