aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/MoonP/ast.cpp63
-rw-r--r--src/MoonP/ast.hpp431
-rw-r--r--src/MoonP/moon_compiler.cpp2
-rw-r--r--src/MoonP/parser.cpp1923
-rw-r--r--src/MoonP/parser.hpp512
5 files changed, 1461 insertions, 1470 deletions
diff --git a/src/MoonP/ast.cpp b/src/MoonP/ast.cpp
index 7cdefba..71c90c5 100644
--- a/src/MoonP/ast.cpp
+++ b/src/MoonP/ast.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 <cassert> 12#include <cassert>
12#include "MoonP/ast.hpp" 13#include "MoonP/ast.hpp"
@@ -48,20 +49,20 @@ bool ast_node::visitChild(const std::function<bool (ast_node*)>&) {
48 return false; 49 return false;
49} 50}
50 51
51 52
52/** Asks all members to construct themselves from the stack. 53/** Asks all members to construct themselves from the stack.
53 The members are asked to construct themselves in reverse order. 54 The members are asked to construct themselves in reverse order.
54 from a node stack. 55 from a node stack.
55 @param st stack. 56 @param st stack.
56 */ 57*/
57void ast_container::construct(ast_stack &st) { 58void ast_container::construct(ast_stack &st) {
58 for(ast_member_vector::reverse_iterator it = m_members.rbegin(); 59 for(ast_member_vector::reverse_iterator it = m_members.rbegin();
59 it != m_members.rend(); 60 it != m_members.rend();
60 ++it) 61 ++it)
61 { 62 {
62 ast_member* member = *it; 63 ast_member* member = *it;
63 member->construct(st); 64 member->construct(st);
64 } 65 }
65} 66}
66 67
67traversal ast_container::traverse(const std::function<traversal (ast_node*)>& func) { 68traversal ast_container::traverse(const std::function<traversal (ast_node*)>& func) {
@@ -108,24 +109,24 @@ bool ast_container::visitChild(const std::function<bool (ast_node*)>& func) {
108 109
109 110
110/** parses the given input. 111/** parses the given input.
111 @param i input. 112 @param i input.
112 @param g root rule of grammar. 113 @param g root rule of grammar.
113 @param el list of errors. 114 @param el list of errors.
114 @param ud user data, passed to the parse procedures. 115 @param ud user data, passed to the parse procedures.
115 @return pointer to ast node created, or null if there was an error. 116 @return pointer to ast node created, or null if there was an error.
116 The return object must be deleted by the caller. 117 The return object must be deleted by the caller.
117 */ 118*/
118ast_node* parse(input &i, rule &g, error_list &el, void* ud) { 119ast_node* parse(input& i, rule& g, error_list& el, void* ud) {
119 ast_stack st; 120 ast_stack st;
120 if (!parse(i, g, el, &st, ud)) { 121 if (!parse(i, g, el, &st, ud)) {
121 for (auto node : st) { 122 for (auto node : st) {
122 delete node; 123 delete node;
123 } 124 }
124 st.clear(); 125 st.clear();
125 return nullptr; 126 return nullptr;
126 } 127 }
127 assert(st.size() == 1); 128 assert(st.size() == 1);
128 return st.front(); 129 return st.front();
129} 130}
130 131
131 132
diff --git a/src/MoonP/ast.hpp b/src/MoonP/ast.hpp
index 38141e2..8bcfc21 100644
--- a/src/MoonP/ast.hpp
+++ b/src/MoonP/ast.hpp
@@ -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#pragma once 12#pragma once
12 13
@@ -28,7 +29,7 @@ template <class T> class ast;
28 29
29 30
30/** type of AST node stack. 31/** type of AST node stack.
31 */ 32*/
32typedef std::vector<ast_node*> ast_stack; 33typedef std::vector<ast_node*> ast_stack;
33typedef std::list<ast_node*> node_container; 34typedef std::list<ast_node*> node_container;
34 35
@@ -47,7 +48,7 @@ enum class traversal {
47}; 48};
48 49
49/** Base class for AST nodes. 50/** Base class for AST nodes.
50 */ 51*/
51class ast_node : public input_range { 52class ast_node : public input_range {
52public: 53public:
53 ast_node() : _ref(0) {} 54 ast_node() : _ref(0) {}
@@ -63,14 +64,14 @@ public:
63 } 64 }
64 } 65 }
65 66
66 /** interface for filling the contents of the node 67 /** interface for filling the contents of the node
67 from a node stack. 68 from a node stack.
68 @param st stack. 69 @param st stack.
69 */ 70 */
70 virtual void construct(ast_stack&) {} 71 virtual void construct(ast_stack&) {}
71 72
72 /** interface for visiting AST tree use. 73 /** interface for visiting AST tree use.
73 */ 74 */
74 virtual traversal traverse(const std::function<traversal (ast_node*)>& func); 75 virtual traversal traverse(const std::function<traversal (ast_node*)>& func);
75 76
76 template <typename... Ts> 77 template <typename... Ts>
@@ -128,12 +129,12 @@ bool ast_is(ast_node* node) {
128class ast_member; 129class ast_member;
129 130
130/** type of ast member vector. 131/** type of ast member vector.
131 */ 132*/
132typedef std::vector<ast_member*> ast_member_vector; 133typedef std::vector<ast_member*> ast_member_vector;
133 134
134 135
135/** base class for AST nodes with children. 136/** base class for AST nodes with children.
136 */ 137*/
137class ast_container : public ast_node { 138class ast_container : public ast_node {
138public: 139public:
139 void add_members(std::initializer_list<ast_member*> members) { 140 void add_members(std::initializer_list<ast_member*> members) {
@@ -142,42 +143,42 @@ public:
142 } 143 }
143 } 144 }
144 145
145 /** returns the vector of AST members. 146 /** returns the vector of AST members.
146 @return the vector of AST members. 147 @return the vector of AST members.
147 */ 148 */
148 const ast_member_vector& members() const { 149 const ast_member_vector& members() const {
149 return m_members; 150 return m_members;
150 } 151 }
151 152
152 /** Asks all members to construct themselves from the stack. 153 /** Asks all members to construct themselves from the stack.
153 The members are asked to construct themselves in reverse order. 154 The members are asked to construct themselves in reverse order.
154 from a node stack. 155 from a node stack.
155 @param st stack. 156 @param st stack.
156 */ 157 */
157 virtual void construct(ast_stack& st) override; 158 virtual void construct(ast_stack& st) override;
158 159
159 virtual traversal traverse(const std::function<traversal (ast_node*)>& func) override; 160 virtual traversal traverse(const std::function<traversal (ast_node*)>& func) override;
160 161
161 virtual bool visitChild(const std::function<bool (ast_node*)>& func) override; 162 virtual bool visitChild(const std::function<bool (ast_node*)>& func) override;
162private: 163private:
163 ast_member_vector m_members; 164 ast_member_vector m_members;
164 165
165 friend class ast_member; 166 friend class ast_member;
166}; 167};
167 168
168 169
169/** Base class for children of ast_container. 170/** Base class for children of ast_container.
170 */ 171*/
171class ast_member { 172class ast_member {
172public: 173public:
173 virtual ~ast_member() {} 174 virtual ~ast_member() {}
174 175
175 /** interface for filling the the member from a node stack. 176 /** interface for filling the the member from a node stack.
176 @param st stack. 177 @param st stack.
177 */ 178 */
178 virtual void construct(ast_stack& st) = 0; 179 virtual void construct(ast_stack& st) = 0;
179 180
180 virtual bool accept(ast_node* node) = 0; 181 virtual bool accept(ast_node* node) = 0;
181 182
182 virtual int get_type() { return ast_type<ast_member>(); } 183 virtual int get_type() { return ast_type<ast_member>(); }
183}; 184};
@@ -193,12 +194,12 @@ public:
193 if (node) node->retain(); 194 if (node) node->retain();
194 } 195 }
195 196
196 virtual ~_ast_ptr() { 197 virtual ~_ast_ptr() {
197 if (m_ptr) { 198 if (m_ptr) {
198 m_ptr->release(); 199 m_ptr->release();
199 m_ptr = nullptr; 200 m_ptr = nullptr;
200 } 201 }
201 } 202 }
202 203
203 ast_node* get() const { 204 ast_node* get() const {
204 return m_ptr; 205 return m_ptr;
@@ -242,109 +243,109 @@ protected:
242}; 243};
243 244
244/** pointer to an AST object. 245/** pointer to an AST object.
245 It assumes ownership of the object. 246 It assumes ownership of the object.
246 It pops an object of the given type from the stack. 247 It pops an object of the given type from the stack.
247 @tparam Required if true, the object is required. 248 @tparam Required if true, the object is required.
248 @tparam T type of object to control. 249 @tparam T type of object to control.
249 */ 250*/
250template <bool Required, class T> class ast_ptr : public _ast_ptr { 251template <bool Required, class T> class ast_ptr : public _ast_ptr {
251public: 252public:
252 ast_ptr(T* node = nullptr) : _ast_ptr(node) {} 253 ast_ptr(T* node = nullptr) : _ast_ptr(node) {}
253 254
254 ast_ptr(const ast_ptr& other) : _ast_ptr(other.get()) {} 255 ast_ptr(const ast_ptr& other) : _ast_ptr(other.get()) {}
255 256
256 ast_ptr& operator=(const ast_ptr& other) { 257 ast_ptr& operator=(const ast_ptr& other) {
257 set(other.get()); 258 set(other.get());
258 return *this; 259 return *this;
259 } 260 }
260 261
261 /** gets the underlying ptr value. 262 /** gets the underlying ptr value.
262 @return the underlying ptr value. 263 @return the underlying ptr value.
263 */ 264 */
264 T* get() const { 265 T* get() const {
265 return static_cast<T*>(m_ptr); 266 return static_cast<T*>(m_ptr);
266 } 267 }
267 268
268 /** auto conversion to the underlying object ptr. 269 /** auto conversion to the underlying object ptr.
269 @return the underlying ptr value. 270 @return the underlying ptr value.
270 */ 271 */
271 operator T*() const { 272 operator T*() const {
272 return static_cast<T*>(m_ptr); 273 return static_cast<T*>(m_ptr);
273 } 274 }
274 275
275 /** member access. 276 /** member access.
276 @return the underlying ptr value. 277 @return the underlying ptr value.
277 */ 278 */
278 T* operator->() const { 279 T* operator->() const {
279 assert(m_ptr); 280 assert(m_ptr);
280 return static_cast<T*>(m_ptr); 281 return static_cast<T*>(m_ptr);
281 } 282 }
282 283
283 /** Pops a node from the stack. 284 /** Pops a node from the stack.
284 @param st stack. 285 @param st stack.
285 @exception std::logic_error thrown if the node is not of the appropriate type; 286 @exception std::logic_error thrown if the node is not of the appropriate type;
286 thrown only if Required == true or if the stack is empty. 287 thrown only if Required == true or if the stack is empty.
287 */ 288 */
288 virtual void construct(ast_stack& st) override { 289 virtual void construct(ast_stack& st) override {
289 // check the stack node 290 // check the stack node
290 if (st.empty()) { 291 if (st.empty()) {
291 if (!Required) return; 292 if (!Required) return;
292 throw std::logic_error("Invalid AST stack."); 293 throw std::logic_error("Invalid AST stack.");
293 } 294 }
294 ast_node* node = st.back(); 295 ast_node* node = st.back();
295 if (!ast_ptr::accept(node)) { 296 if (!ast_ptr::accept(node)) {
296 // if the object is not required, simply return 297 // if the object is not required, simply return
297 if (!Required) return; 298 if (!Required) return;
298 // else if the object is mandatory, throw an exception 299 // else if the object is mandatory, throw an exception
299 throw std::logic_error("Invalid AST node."); 300 throw std::logic_error("Invalid AST node.");
300 } 301 }
301 st.pop_back(); 302 st.pop_back();
302 m_ptr = node; 303 m_ptr = node;
303 node->retain(); 304 node->retain();
304 } 305 }
305private: 306private:
306 virtual bool accept(ast_node* node) override { 307 virtual bool accept(ast_node* node) override {
307 return node && (std::is_same<ast_node,T>() || ast_type<T>() == node->get_type()); 308 return node && (std::is_same<ast_node,T>() || ast_type<T>() == node->get_type());
308 } 309 }
309}; 310};
310 311
311template <bool Required, class ...Args> class ast_sel : public _ast_ptr { 312template <bool Required, class ...Args> class ast_sel : public _ast_ptr {
312public: 313public:
313 ast_sel() : _ast_ptr(nullptr) {} 314 ast_sel() : _ast_ptr(nullptr) {}
314 315
315 ast_sel(const ast_sel& other) : _ast_ptr(other.get()) {} 316 ast_sel(const ast_sel& other) : _ast_ptr(other.get()) {}
316 317
317 ast_sel& operator=(const ast_sel& other) { 318 ast_sel& operator=(const ast_sel& other) {
318 set(other.get()); 319 set(other.get());
319 return *this; 320 return *this;
320 } 321 }
321 322
322 operator ast_node*() const { 323 operator ast_node*() const {
323 return m_ptr; 324 return m_ptr;
324 } 325 }
325 326
326 ast_node* operator->() const { 327 ast_node* operator->() const {
327 assert(m_ptr); 328 assert(m_ptr);
328 return m_ptr; 329 return m_ptr;
329 } 330 }
330 331
331 virtual void construct(ast_stack& st) override { 332 virtual void construct(ast_stack& st) override {
332 if (st.empty()) { 333 if (st.empty()) {
333 if (!Required) return; 334 if (!Required) return;
334 throw std::logic_error("Invalid AST stack."); 335 throw std::logic_error("Invalid AST stack.");
335 } 336 }
336 ast_node* node = st.back(); 337 ast_node* node = st.back();
337 if (!ast_sel::accept(node)) { 338 if (!ast_sel::accept(node)) {
338 if (!Required) return; 339 if (!Required) return;
339 throw std::logic_error("Invalid AST node."); 340 throw std::logic_error("Invalid AST node.");
340 } 341 }
341 st.pop_back(); 342 st.pop_back();
342 m_ptr = node; 343 m_ptr = node;
343 node->retain(); 344 node->retain();
344 } 345 }
345private: 346private:
346 virtual bool accept(ast_node* node) override { 347 virtual bool accept(ast_node* node) override {
347 if (!node) return false; 348 if (!node) return false;
348 using swallow = bool[]; 349 using swallow = bool[];
349 bool result = false; 350 bool result = false;
350 (void)swallow{result || (result = ast_type<Args>() == node->get_type())...}; 351 (void)swallow{result || (result = ast_type<Args>() == node->get_type())...};
@@ -355,8 +356,8 @@ private:
355class _ast_list : public ast_member { 356class _ast_list : public ast_member {
356public: 357public:
357 ~_ast_list() { 358 ~_ast_list() {
358 clear(); 359 clear();
359 } 360 }
360 361
361 inline ast_node* back() const { 362 inline ast_node* back() const {
362 return m_objects.back(); 363 return m_objects.back();
@@ -374,14 +375,14 @@ public:
374 return m_objects.empty(); 375 return m_objects.empty();
375 } 376 }
376 377
377 void push_back(ast_node* node) { 378 void push_back(ast_node* node) {
378 assert(node && accept(node)); 379 assert(node && accept(node));
379 m_objects.push_back(node); 380 m_objects.push_back(node);
380 node->retain(); 381 node->retain();
381 } 382 }
382 383
383 void push_front(ast_node* node) { 384 void push_front(ast_node* node) {
384 assert(node && accept(node)); 385 assert(node && accept(node));
385 m_objects.push_front(node); 386 m_objects.push_front(node);
386 node->retain(); 387 node->retain();
387 } 388 }
@@ -399,22 +400,22 @@ public:
399 } 400 }
400 401
401 const node_container& objects() const { 402 const node_container& objects() const {
402 return m_objects; 403 return m_objects;
403 } 404 }
404 405
405 void clear() { 406 void clear() {
406 for(ast_node* obj : m_objects) { 407 for(ast_node* obj : m_objects) {
407 if (obj) obj->release(); 408 if (obj) obj->release();
408 } 409 }
409 m_objects.clear(); 410 m_objects.clear();
410 } 411 }
411 412
412 void dup(const _ast_list& src) { 413 void dup(const _ast_list& src) {
413 for(ast_node* obj : src.m_objects) { 414 for(ast_node* obj : src.m_objects) {
414 m_objects.push_back(obj); 415 m_objects.push_back(obj);
415 obj->retain(); 416 obj->retain();
416 } 417 }
417 } 418 }
418 419
419 virtual int get_type() override { return ast_type<_ast_list>(); } 420 virtual int get_type() override { return ast_type<_ast_list>(); }
420protected: 421protected:
@@ -422,50 +423,50 @@ protected:
422}; 423};
423 424
424/** A list of objects. 425/** A list of objects.
425 It pops objects of the given type from the ast stack, until no more objects can be popped. 426 It pops objects of the given type from the ast stack, until no more objects can be popped.
426 It assumes ownership of objects. 427 It assumes ownership of objects.
427 @tparam Required if true, the object is required. 428 @tparam Required if true, the object is required.
428 @tparam T type of object to control. 429 @tparam T type of object to control.
429 */ 430*/
430template <bool Required, class T> class ast_list : public _ast_list { 431template <bool Required, class T> class ast_list : public _ast_list {
431public: 432public:
432 ast_list() { } 433 ast_list() { }
433 434
434 ast_list(const ast_list& other) { 435 ast_list(const ast_list& other) {
435 dup(other); 436 dup(other);
436 } 437 }
437 438
438 ast_list& operator=(const ast_list& other) { 439 ast_list& operator=(const ast_list& other) {
439 clear(); 440 clear();
440 dup(other); 441 dup(other);
441 return *this; 442 return *this;
442 } 443 }
443 444
444 /** Pops objects of type T from the stack until no more objects can be popped. 445 /** Pops objects of type T from the stack until no more objects can be popped.
445 @param st stack. 446 @param st stack.
446 */ 447 */
447 virtual void construct(ast_stack &st) override { 448 virtual void construct(ast_stack &st) override {
448 while (!st.empty()) { 449 while (!st.empty()) {
449 ast_node* node = st.back(); 450 ast_node* node = st.back();
450 // if the object was not not of the appropriate type, 451 // if the object was not not of the appropriate type,
451 // end the list parsing 452 // end the list parsing
452 if (!ast_list::accept(node)) { 453 if (!ast_list::accept(node)) {
453 if (Required && m_objects.empty()) { 454 if (Required && m_objects.empty()) {
454 throw std::logic_error("Invalid AST node."); 455 throw std::logic_error("Invalid AST node.");
455 } 456 }
456 return; 457 return;
457 } 458 }
458 st.pop_back(); 459 st.pop_back();
459 // insert the object in the list, in reverse order 460 // insert the object in the list, in reverse order
460 m_objects.push_front(node); 461 m_objects.push_front(node);
461 node->retain(); 462 node->retain();
462 } 463 }
463 if (Required && m_objects.empty()) { 464 if (Required && m_objects.empty()) {
464 throw std::logic_error("Invalid AST stack."); 465 throw std::logic_error("Invalid AST stack.");
465 } 466 }
466 } 467 }
467private: 468private:
468 virtual bool accept(ast_node* node) override { 469 virtual bool accept(ast_node* node) override {
469 return node && (std::is_same<ast_node,T>() || ast_type<T>() == node->get_type()); 470 return node && (std::is_same<ast_node,T>() || ast_type<T>() == node->get_type());
470 } 471 }
471}; 472};
@@ -474,36 +475,36 @@ template <bool Required, class ...Args> class ast_sel_list : public _ast_list {
474public: 475public:
475 ast_sel_list() { } 476 ast_sel_list() { }
476 477
477 ast_sel_list(const ast_sel_list& other) { 478 ast_sel_list(const ast_sel_list& other) {
478 dup(other); 479 dup(other);
479 } 480 }
480 481
481 ast_sel_list& operator=(const ast_sel_list& other) { 482 ast_sel_list& operator=(const ast_sel_list& other) {
482 clear(); 483 clear();
483 dup(other); 484 dup(other);
484 return *this; 485 return *this;
485 } 486 }
486 487
487 virtual void construct(ast_stack &st) override { 488 virtual void construct(ast_stack &st) override {
488 while (!st.empty()) { 489 while (!st.empty()) {
489 ast_node* node = st.back(); 490 ast_node* node = st.back();
490 if (!ast_sel_list::accept(node)) { 491 if (!ast_sel_list::accept(node)) {
491 if (Required && m_objects.empty()) { 492 if (Required && m_objects.empty()) {
492 throw std::logic_error("Invalid AST node."); 493 throw std::logic_error("Invalid AST node.");
493 } 494 }
494 return; 495 return;
495 } 496 }
496 st.pop_back(); 497 st.pop_back();
497 m_objects.push_front(node); 498 m_objects.push_front(node);
498 node->retain(); 499 node->retain();
499 } 500 }
500 if (Required && m_objects.empty()) { 501 if (Required && m_objects.empty()) {
501 throw std::logic_error("Invalid AST stack."); 502 throw std::logic_error("Invalid AST stack.");
502 } 503 }
503 } 504 }
504private: 505private:
505 virtual bool accept(ast_node* node) override { 506 virtual bool accept(ast_node* node) override {
506 if (!node) return false; 507 if (!node) return false;
507 using swallow = bool[]; 508 using swallow = bool[];
508 bool result = false; 509 bool result = false;
509 (void)swallow{result || (result = ast_type<Args>() == node->get_type())...}; 510 (void)swallow{result || (result = ast_type<Args>() == node->get_type())...};
@@ -512,37 +513,37 @@ private:
512}; 513};
513 514
514/** AST function which creates an object of type T 515/** AST function which creates an object of type T
515 and pushes it to the node stack. 516 and pushes it to the node stack.
516 */ 517*/
517template <class T> class ast { 518template <class T> class ast {
518public: 519public:
519 /** constructor. 520 /** constructor.
520 @param r rule to attach the AST function to. 521 @param r rule to attach the AST function to.
521 */ 522 */
522 ast(rule& r) { 523 ast(rule& r) {
523 r.set_parse_proc(&_parse_proc); 524 r.set_parse_proc(&_parse_proc);
524 } 525 }
525private: 526private:
526 //parse proc 527 //parse proc
527 static void _parse_proc(const pos& b, const pos& e, void* d) { 528 static void _parse_proc(const pos& b, const pos& e, void* d) {
528 ast_stack* st = reinterpret_cast<ast_stack*>(d); 529 ast_stack* st = reinterpret_cast<ast_stack*>(d);
529 T* obj = new T; 530 T* obj = new T;
530 obj->m_begin = b; 531 obj->m_begin = b;
531 obj->m_end = e; 532 obj->m_end = e;
532 obj->construct(*st); 533 obj->construct(*st);
533 st->push_back(obj); 534 st->push_back(obj);
534 } 535 }
535}; 536};
536 537
537 538
538/** parses the given input. 539/** parses the given input.
539 @param i input. 540 @param i input.
540 @param g root rule of grammar. 541 @param g root rule of grammar.
541 @param el list of errors. 542 @param el list of errors.
542 @param ud user data, passed to the parse procedures. 543 @param ud user data, passed to the parse procedures.
543 @return pointer to ast node created, or null if there was an error. 544 @return pointer to ast node created, or null if there was an error.
544 The return object must be deleted by the caller. 545 The return object must be deleted by the caller.
545 */ 546*/
546ast_node* parse(input& i, rule& g, error_list& el, void* ud); 547ast_node* parse(input& i, rule& g, error_list& el, void* ud);
547 548
548 549
diff --git a/src/MoonP/moon_compiler.cpp b/src/MoonP/moon_compiler.cpp
index d3e78ed..f74d056 100644
--- a/src/MoonP/moon_compiler.cpp
+++ b/src/MoonP/moon_compiler.cpp
@@ -4,7 +4,7 @@ Permission is hereby granted, free of charge, to any person obtaining a copy of
4 4
5The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 5The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6 6
7THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 7THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.*/
8 8
9#include <string> 9#include <string>
10#include <unordered_set> 10#include <unordered_set>
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
diff --git a/src/MoonP/parser.hpp b/src/MoonP/parser.hpp
index b419e8c..01d1050 100644
--- a/src/MoonP/parser.hpp
+++ b/src/MoonP/parser.hpp
@@ -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#pragma once 12#pragma once
12 13
@@ -60,89 +61,89 @@ typedef std::function<bool(const item_t&)> user_handler;
60///position into the input. 61///position into the input.
61class pos { 62class pos {
62public: 63public:
63 ///interator into the input. 64 ///interator into the input.
64 input::iterator m_it; 65 input::iterator m_it;
65 66
66 ///line. 67 ///line.
67 int m_line; 68 int m_line;
68 69
69 ///column. 70 ///column.
70 int m_col; 71 int m_col;
71 72
72 ///null constructor. 73 ///null constructor.
73 pos():m_line(0),m_col(0) {} 74 pos():m_line(0),m_col(0) {}
74 75
75 /** constructor from input. 76 /** constructor from input.
76 @param i input. 77 @param i input.
77 */ 78 */
78 pos(input &i); 79 pos(input &i);
79}; 80};
80 81
81 82
82/** a grammar expression. 83/** a grammar expression.
83 */ 84*/
84class expr { 85class expr {
85public: 86public:
86 /** character terminal constructor. 87 /** character terminal constructor.
87 @param c character. 88 @param c character.
88 */ 89 */
89 expr(char c); 90 expr(char c);
90 91
91 /** null-terminated string terminal constructor. 92 /** null-terminated string terminal constructor.
92 @param s null-terminated string. 93 @param s null-terminated string.
93 */ 94 */
94 expr(const char *s); 95 expr(const char* s);
95 96
96 /** rule reference constructor. 97 /** rule reference constructor.
97 @param r rule. 98 @param r rule.
98 */ 99 */
99 expr(rule &r); 100 expr(rule& r);
100 101
101 /** creates a zero-or-more loop out of this expression. 102 /** creates a zero-or-more loop out of this expression.
102 @return a zero-or-more loop expression. 103 @return a zero-or-more loop expression.
103 */ 104 */
104 expr operator *() const; 105 expr operator*() const;
105 106
106 /** creates a one-or-more loop out of this expression. 107 /** creates a one-or-more loop out of this expression.
107 @return a one-or-more loop expression. 108 @return a one-or-more loop expression.
108 */ 109 */
109 expr operator +() const; 110 expr operator+() const;
110 111
111 /** creates an optional out of this expression. 112 /** creates an optional out of this expression.
112 @return an optional expression. 113 @return an optional expression.
113 */ 114 */
114 expr operator -() const; 115 expr operator-() const;
115 116
116 /** creates an AND-expression. 117 /** creates an AND-expression.
117 @return an AND-expression. 118 @return an AND-expression.
118 */ 119 */
119 expr operator &() const; 120 expr operator&() const;
120 121
121 /** creates a NOT-expression. 122 /** creates a NOT-expression.
122 @return a NOT-expression. 123 @return a NOT-expression.
123 */ 124 */
124 expr operator !() const; 125 expr operator!() const;
125 126
126private: 127private:
127 //internal expression 128 //internal expression
128 _expr *m_expr; 129 _expr* m_expr;
129 130
130 //internal constructor from internal expression 131 //internal constructor from internal expression
131 expr(_expr *e) : m_expr(e) {} 132 expr(_expr* e) : m_expr(e) {}
132 133
133 //assignment not allowed 134 //assignment not allowed
134 expr &operator = (expr &); 135 expr& operator=(expr&);
135 136
136 friend class _private; 137 friend class _private;
137}; 138};
138 139
139 140
140/** type of procedure to invoke when a rule is successfully parsed. 141/** type of procedure to invoke when a rule is successfully parsed.
141 @param b begin position of input. 142 @param b begin position of input.
142 @param e end position of input. 143 @param e end position of input.
143 @param d pointer to user data. 144 @param d pointer to user data.
144 */ 145*/
145typedef void (*parse_proc)(const pos &b, const pos &e, void *d); 146typedef void (*parse_proc)(const pos& b, const pos& e, void* d);
146 147
147 148
148///input range. 149///input range.
@@ -150,54 +151,54 @@ class input_range {
150public: 151public:
151 virtual ~input_range() {} 152 virtual ~input_range() {}
152 153
153 ///begin position. 154 ///begin position.
154 pos m_begin; 155 pos m_begin;
155 156
156 ///end position. 157 ///end position.
157 pos m_end; 158 pos m_end;
158 159
159 ///empty constructor. 160 ///empty constructor.
160 input_range() {} 161 input_range() {}
161 162
162 /** constructor. 163 /** constructor.
163 @param b begin position. 164 @param b begin position.
164 @param e end position. 165 @param e end position.
165 */ 166 */
166 input_range(const pos &b, const pos &e); 167 input_range(const pos& b, const pos& e);
167}; 168};
168 169
169 170
170///enum with error types. 171///enum with error types.
171enum ERROR_TYPE { 172enum ERROR_TYPE {
172 ///syntax error 173 ///syntax error
173 ERROR_SYNTAX_ERROR = 1, 174 ERROR_SYNTAX_ERROR = 1,
174 175
175 ///invalid end of file 176 ///invalid end of file
176 ERROR_INVALID_EOF, 177 ERROR_INVALID_EOF,
177 178
178 ///first user error 179 ///first user error
179 ERROR_USER = 100 180 ERROR_USER = 100
180}; 181};
181 182
182 183
183///error. 184///error.
184class error : public input_range { 185class error : public input_range {
185public: 186public:
186 ///type 187 ///type
187 int m_type; 188 int m_type;
188 189
189 /** constructor. 190 /** constructor.
190 @param b begin position. 191 @param b begin position.
191 @param e end position. 192 @param e end position.
192 @param t type. 193 @param t type.
193 */ 194 */
194 error(const pos &b, const pos &e, int t); 195 error(const pos& b, const pos& e, int t);
195 196
196 /** compare on begin position. 197 /** compare on begin position.
197 @param e the other error to compare this with. 198 @param e the other error to compare this with.
198 @return true if this comes before the previous error, false otherwise. 199 @return true if this comes before the previous error, false otherwise.
199 */ 200 */
200 bool operator < (const error &e) const; 201 bool operator<(const error& e) const;
201}; 202};
202 203
203 204
@@ -206,189 +207,189 @@ typedef std::list<error> error_list;
206 207
207 208
208/** represents a rule. 209/** represents a rule.
209 */ 210*/
210class rule { 211class rule {
211public: 212public:
212 /** character terminal constructor. 213 /** character terminal constructor.
213 @param c character. 214 @param c character.
214 */ 215 */
215 rule(); 216 rule();
216 rule(char c); 217 rule(char c);
217 218
218 /** null-terminated string terminal constructor. 219 /** null-terminated string terminal constructor.
219 @param s null-terminated string. 220 @param s null-terminated string.
220 */ 221 */
221 rule(const char *s); 222 rule(const char* s);
222 223
223 /** constructor from expression. 224 /** constructor from expression.
224 @param e expression. 225 @param e expression.
225 */ 226 */
226 rule(const expr &e); 227 rule(const expr& e);
227 228
228 /** constructor from rule. 229 /** constructor from rule.
229 @param r rule. 230 @param r rule.
230 */ 231 */
231 rule(rule &r); 232 rule(rule& r);
232 233
233 /** invalid constructor from rule (required by gcc). 234 /** invalid constructor from rule (required by gcc).
234 @param r rule. 235 @param r rule.
235 @exception std::logic_error always thrown. 236 @exception std::logic_error always thrown.
236 */ 237 */
237 rule(const rule &r); 238 rule(const rule& r);
238 239
239 /** deletes the internal object that represents the expression. 240 /** deletes the internal object that represents the expression.
240 */ 241 */
241 ~rule(); 242 ~rule();
242 243
243 /** creates a zero-or-more loop out of this rule. 244 /** creates a zero-or-more loop out of this rule.
244 @return a zero-or-more loop rule. 245 @return a zero-or-more loop rule.
245 */ 246 */
246 expr operator *(); 247 expr operator*();
247 248
248 /** creates a one-or-more loop out of this rule. 249 /** creates a one-or-more loop out of this rule.
249 @return a one-or-more loop rule. 250 @return a one-or-more loop rule.
250 */ 251 */
251 expr operator +(); 252 expr operator+();
252 253
253 /** creates an optional out of this rule. 254 /** creates an optional out of this rule.
254 @return an optional rule. 255 @return an optional rule.
255 */ 256 */
256 expr operator -(); 257 expr operator-();
257 258
258 /** creates an AND-expression out of this rule. 259 /** creates an AND-expression out of this rule.
259 @return an AND-expression out of this rule. 260 @return an AND-expression out of this rule.
260 */ 261 */
261 expr operator &(); 262 expr operator&();
262 263
263 /** creates a NOT-expression out of this rule. 264 /** creates a NOT-expression out of this rule.
264 @return a NOT-expression out of this rule. 265 @return a NOT-expression out of this rule.
265 */ 266 */
266 expr operator !(); 267 expr operator!();
267 268
268 /** sets the parse procedure. 269 /** sets the parse procedure.
269 @param p procedure. 270 @param p procedure.
270 */ 271 */
271 void set_parse_proc(parse_proc p); 272 void set_parse_proc(parse_proc p);
272 273
273 /** get the this ptr (since operator & is overloaded). 274 /** get the this ptr (since operator & is overloaded).
274 @return pointer to this. 275 @return pointer to this.
275 */ 276 */
276 rule *this_ptr() { return this; } 277 rule* this_ptr() { return this; }
277 278
278 rule &operator = (rule &); 279 rule& operator=(rule&);
279 280
280 rule &operator = (const expr &); 281 rule& operator=(const expr&);
281 282
282private: 283private:
283 //mode 284 //mode
284 enum _MODE { 285 enum _MODE {
285 _PARSE, 286 _PARSE,
286 _REJECT, 287 _REJECT,
287 _ACCEPT 288 _ACCEPT
288 }; 289 };
289 290
290 //state 291 //state
291 struct _state { 292 struct _state {
292 //position in source code, relative to start 293 //position in source code, relative to start
293 size_t m_pos; 294 size_t m_pos;
294 295
295 //mode 296 //mode
296 _MODE m_mode; 297 _MODE m_mode;
297 298
298 //constructor 299 //constructor
299 _state(size_t pos = -1, _MODE mode = _PARSE) : 300 _state(size_t pos = -1, _MODE mode = _PARSE) :
300 m_pos(pos), m_mode(mode) {} 301 m_pos(pos), m_mode(mode) {}
301 }; 302 };
302 303
303 //internal expression 304 //internal expression
304 _expr *m_expr; 305 _expr* m_expr;
305 306
306 //associated parse procedure. 307 //associated parse procedure.
307 parse_proc m_parse_proc; 308 parse_proc m_parse_proc;
308 309
309 //state 310 //state
310 _state m_state; 311 _state m_state;
311 312
312 friend class _private; 313 friend class _private;
313 friend class _context; 314 friend class _context;
314}; 315};
315 316
316 317
317/** creates a sequence of expressions. 318/** creates a sequence of expressions.
318 @param left left operand. 319 @param left left operand.
319 @param right right operand. 320 @param right right operand.
320 @return an expression which parses a sequence. 321 @return an expression which parses a sequence.
321 */ 322*/
322expr operator >> (const expr &left, const expr &right); 323expr operator>>(const expr& left, const expr& right);
323 324
324 325
325/** creates a choice of expressions. 326/** creates a choice of expressions.
326 @param left left operand. 327 @param left left operand.
327 @param right right operand. 328 @param right right operand.
328 @return an expression which parses a choice. 329 @return an expression which parses a choice.
329 */ 330*/
330expr operator | (const expr &left, const expr &right); 331expr operator|(const expr& left, const expr& right);
331 332
332 333
333/** converts a parser expression into a terminal. 334/** converts a parser expression into a terminal.
334 @param e expression. 335 @param e expression.
335 @return an expression which parses a terminal. 336 @return an expression which parses a terminal.
336 */ 337*/
337expr term(const expr &e); 338expr term(const expr& e);
338 339
339 340
340/** creates a set expression from a null-terminated string. 341/** creates a set expression from a null-terminated string.
341 @param s null-terminated string with characters of the set. 342 @param s null-terminated string with characters of the set.
342 @return an expression which parses a single character out of a set. 343 @return an expression which parses a single character out of a set.
343 */ 344*/
344expr set(const char *s); 345expr set(const char* s);
345 346
346 347
347/** creates a range expression. 348/** creates a range expression.
348 @param min min character. 349 @param min min character.
349 @param max max character. 350 @param max max character.
350 @return an expression which parses a single character out of range. 351 @return an expression which parses a single character out of range.
351 */ 352*/
352expr range(int min, int max); 353expr range(int min, int max);
353 354
354 355
355/** creates an expression which increments the line counter 356/** creates an expression which increments the line counter
356 and resets the column counter when the given expression 357 and resets the column counter when the given expression
357 is parsed successfully; used for newline characters. 358 is parsed successfully; used for newline characters.
358 @param e expression to wrap into a newline parser. 359 @param e expression to wrap into a newline parser.
359 @return an expression that handles newlines. 360 @return an expression that handles newlines.
360 */ 361*/
361expr nl(const expr &e); 362expr nl(const expr& e);
362 363
363 364
364/** creates an expression which tests for the end of input. 365/** creates an expression which tests for the end of input.
365 @return an expression that handles the end of input. 366 @return an expression that handles the end of input.
366 */ 367*/
367expr eof(); 368expr eof();
368 369
369 370
370/** creates a not expression. 371/** creates a not expression.
371 @param e expression. 372 @param e expression.
372 @return the appropriate expression. 373 @return the appropriate expression.
373 */ 374*/
374expr not_(const expr &e); 375expr not_(const expr& e);
375 376
376 377
377/** creates an and expression. 378/** creates an and expression.
378 @param e expression. 379 @param e expression.
379 @return the appropriate expression. 380 @return the appropriate expression.
380 */ 381*/
381expr and_(const expr &e); 382expr and_(const expr& e);
382 383
383 384
384/** creates an expression that parses any character. 385/** creates an expression that parses any character.
385 @return the appropriate expression. 386 @return the appropriate expression.
386 */ 387*/
387expr any(); 388expr any();
388 389
389 390
390/** parsing succeeds without consuming any input. 391/** parsing succeeds without consuming any input.
391 */ 392*/
392expr true_(); 393expr true_();
393 394
394 395
@@ -399,34 +400,33 @@ expr false_();
399 400
400/** parse with target expression and let user handle result. 401/** parse with target expression and let user handle result.
401*/ 402*/
402expr user(const expr &e, const user_handler& handler); 403expr user(const expr& e, const user_handler& handler);
403 404
404 405
405/** parses the given input. 406/** parses the given input.
406 The parse procedures of each rule parsed are executed 407 The parse procedures of each rule parsed are executed
407 before this function returns, if parsing succeeds. 408 before this function returns, if parsing succeeds.
408 @param i input. 409 @param i input.
409 @param g root rule of grammar. 410 @param g root rule of grammar.
410 @param el list of errors. 411 @param el list of errors.
411 @param d user data, passed to the parse procedures. 412 @param d user data, passed to the parse procedures.
412 @return true on parsing success, false on failure. 413 @return true on parsing success, false on failure.
413 */ 414*/
414bool parse(input &i, rule &g, error_list &el, void *d, void* ud); 415bool parse(input& i, rule& g, error_list& el, void* d, void* ud);
415 416
416 417
417/** output the specific input range to the specific stream. 418/** output the specific input range to the specific stream.
418 @param stream stream. 419 @param stream stream.
419 @param ir input range. 420 @param ir input range.
420 @return the stream. 421 @return the stream.
421 */ 422*/
422template <class T> T &operator << (T &stream, const input_range &ir) { 423template <class T> T& operator<<(T& stream, const input_range& ir) {
423 for(input::const_iterator it = ir.m_begin.m_it; 424 for(input::const_iterator it = ir.m_begin.m_it;
424 it != ir.m_end.m_it; 425 it != ir.m_end.m_it;
425 ++it) 426 ++it) {
426 { 427 stream << (typename T::char_type)*it;
427 stream << (typename T::char_type)*it; 428 }
428 } 429 return stream;
429 return stream;
430} 430}
431 431
432 432