aboutsummaryrefslogtreecommitdiff
path: root/src/MoonP/parser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/MoonP/parser.cpp')
-rw-r--r--src/MoonP/parser.cpp1923
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
2All rights reserved. 2All 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: 4Redistribution 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. 6Redistributions 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
9THIS 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. */ 8Redistributions 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
10THIS 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.
25class _private { 26class _private {
26public: 27public:
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
53class _state { 54class _state {
54public: 55public:
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
67class _match { 68class _match {
68public: 69public:
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
180private: 181private:
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
190class _expr { 191class _expr {
191public: 192public:
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.
205class _char : public _expr { 206class _char : public _expr {
206public: 207public:
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
223private: 224private:
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.
243class _string : public _expr { 244class _string : public _expr {
244public: 245public:
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
261private: 262private:
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.
283class _set : public _expr { 284class _set : public _expr {
284public: 285public:
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
313private: 314private:
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
351class _unary : public _expr { 352class _unary : public _expr {
352public: 353public:
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
364protected: 365protected:
365 //expression 366 //expression
366 _expr *m_expr; 367 _expr *m_expr;
367}; 368};
368 369
369 370
370//terminal 371//terminal
371class _term : public _unary { 372class _term : public _unary {
372public: 373public:
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:
392class _user : public _unary { 393class _user : public _unary {
393public: 394public:
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
426class _loop0 : public _unary { 427class _loop0 : public _unary {
427public: 428public:
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
479class _loop1 : public _unary { 480class _loop1 : public _unary {
480public: 481public:
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
524class _optional : public _unary { 525class _optional : public _unary {
525public: 526public:
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
549class _and : public _unary { 550class _and : public _unary {
550public: 551public:
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
576class _not : public _unary { 577class _not : public _unary {
577public: 578public:
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
603class _nl : public _unary { 604class _nl : public _unary {
604public: 605public:
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
628class _binary : public _expr { 629class _binary : public _expr {
629public: 630public:
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
642protected: 643protected:
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
649class _seq : public _binary { 650class _seq : public _binary {
650public: 651public:
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
672class _choice : public _binary { 673class _choice : public _binary {
673public: 674public:
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
699class _ref : public _expr { 700class _ref : public _expr {
700public: 701public:
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
717private: 718private:
718 //reference 719 //reference
719 rule &m_rule; 720 rule &m_rule;
720}; 721};
721 722
722 723
723//eof 724//eof
724class _eof : public _expr { 725class _eof : public _expr {
725public: 726public:
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
739class _any : public _expr { 740class _any : public _expr {
740public: 741public:
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:
759class _true : public _expr { 760class _true : public _expr {
760public: 761public:
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:
774class _false: public _expr { 775class _false: public _expr {
775public: 776public:
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
788struct _lr_ok { 789struct _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.
803bool _context::parse_non_term(rule &r) { 804bool _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.
906bool _context::parse_term(rule &r) { 907bool _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.
1009bool _context::_parse_non_term(rule &r) { 1010bool _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.
1026bool _context::_parse_term(rule &r) { 1027bool _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
1043static error _syntax_error(_context &con) { 1044static 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
1049static error _eof_error(_context &con) { 1050static 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*/
1057pos::pos(input &i) : 1058pos::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*/
1068expr::expr(char c) : 1069expr::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*/
1077expr::expr(const char *s) : 1078expr::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*/
1086expr::expr(rule &r) : 1087expr::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*/
1095expr expr::operator *() const { 1096expr 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*/
1103expr expr::operator +() const { 1104expr 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*/
1111expr expr::operator -() const { 1112expr 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*/
1119expr expr::operator &() const { 1120expr 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*/
1127expr expr::operator !() const { 1128expr 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*/
1136input_range::input_range(const pos &b, const pos &e) : 1137input_range::input_range(const pos& b, const pos& e) :
1137m_begin(b), 1138m_begin(b),
1138m_end(e) {} 1139m_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*/
1146error::error(const pos &b, const pos &e, int t) : 1147error::error(const pos& b, const pos& e, int t) :
1147input_range(b, e), 1148input_range(b, e),
1148m_type(t) {} 1149m_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*/
1155bool error::operator < (const error &e) const { 1156bool 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
1159rule::rule() : 1160rule::rule() :
1160 m_expr(nullptr), 1161m_expr(nullptr),
1161 m_parse_proc(nullptr) 1162m_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*/
1168rule::rule(char c) : 1167rule::rule(char c) :
1169 m_expr(new _char(c)), 1168m_expr(new _char(c)),
1170 m_parse_proc(nullptr) 1169m_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*/
1178rule::rule(const char *s) : 1174rule::rule(const char* s) :
1179 m_expr(new _string(s)), 1175m_expr(new _string(s)),
1180 m_parse_proc(nullptr) 1176m_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*/
1188rule::rule(const expr &e) : 1181rule::rule(const expr& e) :
1189 m_expr(_private::get_expr(e)), 1182m_expr(_private::get_expr(e)),
1190 m_parse_proc(nullptr) 1183m_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*/
1198rule::rule(rule &r) : 1189rule::rule(rule& r) :
1199 m_expr(new _ref(r)), 1190m_expr(new _ref(r)),
1200 m_parse_proc(nullptr) 1191m_parse_proc(nullptr) {}
1201{
1202}
1203 1192
1204rule& rule::operator = (rule & r) { 1193rule& 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
1209rule &rule::operator = (const expr & e) { 1198rule &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*/
1217rule::rule(const rule &) { 1206rule::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*/
1224rule::~rule() { 1213rule::~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*/
1232expr rule::operator *() { 1221expr 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*/
1240expr rule::operator +() { 1229expr 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*/
1248expr rule::operator -() { 1237expr 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*/
1256expr rule::operator &() { 1245expr 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*/
1264expr rule::operator !() { 1253expr 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*/
1272void rule::set_parse_proc(parse_proc p) { 1261void 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*/
1283expr operator >> (const expr &left, const expr &right) { 1272expr 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*/
1294expr operator | (const expr &left, const expr &right) { 1283expr 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*/
1304expr term(const expr &e) { 1293expr 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*/
1314expr set(const char *s) { 1303expr 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*/
1324expr range(int min, int max) { 1313expr 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*/
1335expr nl(const expr &e) { 1324expr 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*/
1343expr eof() { 1332expr 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*/
1352expr not_(const expr &e) { 1341expr 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*/
1361expr and_(const expr &e) { 1350expr 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*/
1369expr any() { 1358expr 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*/
1390expr user(const expr &e, const user_handler& handler) { 1379expr 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*/
1404bool parse(input &i, rule &g, error_list &el, void *d, void* ud) { 1393bool 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