aboutsummaryrefslogtreecommitdiff
path: root/MoonParser/ast.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'MoonParser/ast.hpp')
-rw-r--r--MoonParser/ast.hpp194
1 files changed, 83 insertions, 111 deletions
diff --git a/MoonParser/ast.hpp b/MoonParser/ast.hpp
index 8d28177..b388e77 100644
--- a/MoonParser/ast.hpp
+++ b/MoonParser/ast.hpp
@@ -1,5 +1,4 @@
1#ifndef AST_HPP 1#pragma once
2#define AST_HPP
3 2
4 3
5#include <cassert> 4#include <cassert>
@@ -13,14 +12,15 @@ namespace parserlib {
13 12
14 13
15class ast_node; 14class ast_node;
16template <class T, bool OPT, bool MEM> class ast_ptr; 15template <bool Required, class T> class ast_ptr;
17template <class T> class ast_list; 16template <bool Required, class T> class ast_list;
18template <class T> class ast; 17template <class T> class ast;
19 18
20 19
21/** type of AST node stack. 20/** type of AST node stack.
22 */ 21 */
23typedef std::vector<ast_node*> ast_stack; 22typedef std::vector<ast_node*> ast_stack;
23typedef std::list<ast_node*> node_container;
24 24
25extern int ast_type_id; 25extern int ast_type_id;
26 26
@@ -78,26 +78,22 @@ public:
78 78
79 virtual bool visitChild(const std::function<bool (ast_node*)>& func); 79 virtual bool visitChild(const std::function<bool (ast_node*)>& func);
80 80
81 virtual ast_node* getChild(int) const { return nullptr; }
82
83 virtual size_t getChildCount() const { return 0; }
84
85 virtual ast_node* getFirstChild() const { return nullptr; }
86
87 virtual ast_node* getLastChild() const { return nullptr; }
88
89 virtual size_t getId() const { return "ast_node"_id; } 81 virtual size_t getId() const { return "ast_node"_id; }
90 82
91 virtual const char* getName() const { return "ast_node"; } 83 virtual const char* getName() const { return "ast_node"; }
92 84
93 virtual int get_type() { return ast_type<ast_node>(); } 85 virtual int get_type() { return ast_type<ast_node>(); }
86
87 template<class T>
88 inline ast_ptr<false, T> new_ptr() {
89 auto item = new T;
90 item->m_begin.m_line = m_begin.m_line;
91 item->m_end.m_line = m_begin.m_line;
92 return ast_ptr<false, T>(item);
93 }
94private: 94private:
95 int _ref; 95 int _ref;
96 ast_node* getByTypeIds(int* begin, int* end); 96 ast_node* getByTypeIds(int* begin, int* end);
97 template <class T, bool OPT, bool MEM> friend class ast_ptr;
98 template <class ...Args> friend class ast_choice;
99 template <class T> friend class ast_list;
100 template <class T> friend class ast;
101}; 97};
102 98
103template<class T> 99template<class T>
@@ -132,9 +128,11 @@ typedef std::vector<ast_member*> ast_member_vector;
132 */ 128 */
133class ast_container : public ast_node { 129class ast_container : public ast_node {
134public: 130public:
135 /** sets the container under construction to be this. 131 void add_members(std::initializer_list<ast_member*> members) {
136 */ 132 for (auto member : members) {
137 ast_container(); 133 m_members.push_back(member);
134 }
135 }
138 136
139 /** returns the vector of AST members. 137 /** returns the vector of AST members.
140 @return the vector of AST members. 138 @return the vector of AST members.
@@ -154,14 +152,6 @@ public:
154 152
155 virtual bool visitChild(const std::function<bool (ast_node*)>& func) override; 153 virtual bool visitChild(const std::function<bool (ast_node*)>& func) override;
156 154
157 virtual ast_node* getChild(int index) const override;
158
159 virtual size_t getChildCount() const override;
160
161 virtual ast_node* getFirstChild() const override;
162
163 virtual ast_node* getLastChild() const override;
164
165 virtual size_t getId() const override { return "ast_container"_id; } 155 virtual size_t getId() const override { return "ast_container"_id; }
166 156
167 virtual const char* getName() const override { return "ast_container"; } 157 virtual const char* getName() const override { return "ast_container"; }
@@ -176,12 +166,6 @@ private:
176 */ 166 */
177class ast_member { 167class ast_member {
178public: 168public:
179 /** automatically registers itself to the container under construction.
180 */
181 ast_member(bool is_member) {
182 if (is_member) add_to_owner();
183 }
184
185 virtual ~ast_member() {} 169 virtual ~ast_member() {}
186 170
187 /** interface for filling the the member from a node stack. 171 /** interface for filling the the member from a node stack.
@@ -192,9 +176,6 @@ public:
192 virtual bool accept(ast_node* node) = 0; 176 virtual bool accept(ast_node* node) = 0;
193 177
194 virtual int get_type() { return ast_type<ast_member>(); } 178 virtual int get_type() { return ast_type<ast_member>(); }
195private:
196 //register the AST member to the current container.
197 void add_to_owner();
198}; 179};
199 180
200template<class T> 181template<class T>
@@ -204,7 +185,7 @@ T* ast_cast(ast_member* member) {
204 185
205class _ast_ptr : public ast_member { 186class _ast_ptr : public ast_member {
206public: 187public:
207 _ast_ptr(ast_node* node, bool is_member) : ast_member(is_member), m_ptr(node) { 188 _ast_ptr(ast_node* node) : m_ptr(node) {
208 if (node) node->retain(); 189 if (node) node->retain();
209 } 190 }
210 191
@@ -226,13 +207,13 @@ public:
226 207
227 template <class T> 208 template <class T>
228 T* to() const { 209 T* to() const {
229 assert(m_ptr->get_type() == ast_type<T>()); 210 assert(m_ptr && m_ptr->get_type() == ast_type<T>());
230 return static_cast<T*>(m_ptr); 211 return static_cast<T*>(m_ptr);
231 } 212 }
232 213
233 template <class T> 214 template <class T>
234 bool is() const { 215 bool is() const {
235 return m_ptr->get_type() == ast_type<T>(); 216 return m_ptr && m_ptr->get_type() == ast_type<T>();
236 } 217 }
237 218
238 void set(ast_node* node) { 219 void set(ast_node* node) {
@@ -259,16 +240,16 @@ protected:
259/** pointer to an AST object. 240/** pointer to an AST object.
260 It assumes ownership of the object. 241 It assumes ownership of the object.
261 It pops an object of the given type from the stack. 242 It pops an object of the given type from the stack.
243 @tparam Required if true, the object is required.
262 @tparam T type of object to control. 244 @tparam T type of object to control.
263 @tparam OPT if true, the object becomes optional.
264 */ 245 */
265template <class T, bool OPT = false, bool MEM = true> class ast_ptr : public _ast_ptr { 246template <bool Required, class T> class ast_ptr : public _ast_ptr {
266public: 247public:
267 ast_ptr(T* node = nullptr) : _ast_ptr(node, MEM) {} 248 ast_ptr(T* node = nullptr) : _ast_ptr(node) {}
268 249
269 ast_ptr(const ast_ptr<T, OPT, MEM>& other) : _ast_ptr(other.get(), MEM) {} 250 ast_ptr(const ast_ptr& other) : _ast_ptr(other.get()) {}
270 251
271 ast_ptr<T, OPT, MEM>& operator=(const ast_ptr<T, OPT, MEM>& other) { 252 ast_ptr& operator=(const ast_ptr& other) {
272 set(other.get()); 253 set(other.get());
273 return *this; 254 return *this;
274 } 255 }
@@ -298,28 +279,22 @@ public:
298 /** Pops a node from the stack. 279 /** Pops a node from the stack.
299 @param st stack. 280 @param st stack.
300 @exception std::logic_error thrown if the node is not of the appropriate type; 281 @exception std::logic_error thrown if the node is not of the appropriate type;
301 thrown only if OPT == false or if the stack is empty. 282 thrown only if Required == true or if the stack is empty.
302 */ 283 */
303 virtual void construct(ast_stack& st) override { 284 virtual void construct(ast_stack& st) override {
304 //check the stack node 285 // check the stack node
305 if (st.empty()) { 286 if (st.empty()) {
306 if (OPT) return; 287 if (!Required) return;
307 else throw std::logic_error("invalid AST stack"); 288 throw std::logic_error("Invalid AST stack");
308 } 289 }
309
310 ast_node* node = st.back(); 290 ast_node* node = st.back();
311
312 if (!ast_ptr::accept(node)) { 291 if (!ast_ptr::accept(node)) {
313 //if the object is optional, simply return 292 // if the object is not required, simply return
314 if (OPT) { 293 if (!Required) return;
315 return; 294 // else if the object is mandatory, throw an exception
316 } else { //else if the object is mandatory, throw an exception 295 throw std::logic_error("Invalid AST node");
317 throw std::logic_error("invalid AST node");
318 }
319 } 296 }
320
321 st.pop_back(); 297 st.pop_back();
322
323 m_ptr = node; 298 m_ptr = node;
324 node->retain(); 299 node->retain();
325 } 300 }
@@ -329,18 +304,13 @@ private:
329 } 304 }
330}; 305};
331 306
332template<class T> 307template <bool Required, class ...Args> class ast_sel : public _ast_ptr {
333inline ast_ptr<T, false, false> new_ptr() {
334 return ast_ptr<T, false, false>(new T);
335}
336
337template <class ...Args> class ast_sel : public _ast_ptr {
338public: 308public:
339 ast_sel() : _ast_ptr(nullptr, true) {} 309 ast_sel() : _ast_ptr(nullptr) {}
340 310
341 ast_sel(const ast_sel<Args...>& other) : _ast_ptr(other.get(), true) {} 311 ast_sel(const ast_sel& other) : _ast_ptr(other.get()) {}
342 312
343 ast_sel<Args...>& operator=(const ast_sel<Args...>& other) { 313 ast_sel& operator=(const ast_sel& other) {
344 set(other.get()); 314 set(other.get());
345 return *this; 315 return *this;
346 } 316 }
@@ -356,15 +326,15 @@ public:
356 326
357 virtual void construct(ast_stack& st) override { 327 virtual void construct(ast_stack& st) override {
358 if (st.empty()) { 328 if (st.empty()) {
359 throw std::logic_error("invalid AST stack"); 329 if (!Required) return;
330 throw std::logic_error("Invalid AST stack");
360 } 331 }
361
362 ast_node* node = st.back(); 332 ast_node* node = st.back();
363 333 if (!ast_sel::accept(node)) {
364 if (!ast_sel::accept(node)) throw std::logic_error("invalid AST node"); 334 if (!Required) return;
365 335 throw std::logic_error("Invalid AST node");
336 }
366 st.pop_back(); 337 st.pop_back();
367
368 m_ptr = node; 338 m_ptr = node;
369 node->retain(); 339 node->retain();
370 } 340 }
@@ -380,10 +350,6 @@ private:
380 350
381class _ast_list : public ast_member { 351class _ast_list : public ast_member {
382public: 352public:
383 typedef std::list<ast_node*> container;
384
385 _ast_list() : ast_member(true) {}
386
387 ~_ast_list() { 353 ~_ast_list() {
388 clear(); 354 clear();
389 } 355 }
@@ -416,6 +382,12 @@ public:
416 node->retain(); 382 node->retain();
417 } 383 }
418 384
385 void pop_front() {
386 auto node = m_objects.front();
387 m_objects.pop_front();
388 node->release();
389 }
390
419 void set_front(ast_node* node) { 391 void set_front(ast_node* node) {
420 assert(node && accept(node)); 392 assert(node && accept(node));
421 m_objects.front()->release(); 393 m_objects.front()->release();
@@ -430,7 +402,7 @@ public:
430 node->retain(); 402 node->retain();
431 } 403 }
432 404
433 const container& objects() const { 405 const node_container& objects() const {
434 return m_objects; 406 return m_objects;
435 } 407 }
436 408
@@ -450,24 +422,24 @@ public:
450 422
451 virtual int get_type() override { return ast_type<_ast_list>(); } 423 virtual int get_type() override { return ast_type<_ast_list>(); }
452protected: 424protected:
453 container m_objects; 425 node_container m_objects;
454}; 426};
455 427
456/** A list of objects. 428/** A list of objects.
457 It pops objects of the given type from the ast stack, until no more objects can be popped. 429 It pops objects of the given type from the ast stack, until no more objects can be popped.
458 It assumes ownership of objects. 430 It assumes ownership of objects.
431 @tparam Required if true, the object is required.
459 @tparam T type of object to control. 432 @tparam T type of object to control.
460 */ 433 */
461template <class T> class ast_list : public _ast_list { 434template <bool Required, class T> class ast_list : public _ast_list {
462public: 435public:
463 ast_list() {} 436 ast_list() { }
464 437
465 ast_list(const ast_list<T>& other) { 438 ast_list(const ast_list& other) {
466 clear();
467 dup(other); 439 dup(other);
468 } 440 }
469 441
470 ast_list<T>& operator=(const ast_list<T>& other) { 442 ast_list& operator=(const ast_list& other) {
471 clear(); 443 clear();
472 dup(other); 444 dup(other);
473 return *this; 445 return *this;
@@ -479,17 +451,22 @@ public:
479 virtual void construct(ast_stack &st) override { 451 virtual void construct(ast_stack &st) override {
480 while (!st.empty()) { 452 while (!st.empty()) {
481 ast_node* node = st.back(); 453 ast_node* node = st.back();
482 454 // if the object was not not of the appropriate type,
483 //if the object was not not of the appropriate type, 455 // end the list parsing
484 //end the list parsing 456 if (!ast_list::accept(node)) {
485 if (!ast_list::accept(node)) return; 457 if (Required && m_objects.empty()) {
486 458 throw std::logic_error("Invalid AST node");
459 }
460 return;
461 }
487 st.pop_back(); 462 st.pop_back();
488 463 // insert the object in the list, in reverse order
489 //insert the object in the list, in reverse order
490 m_objects.push_front(node); 464 m_objects.push_front(node);
491 node->retain(); 465 node->retain();
492 } 466 }
467 if (Required && m_objects.empty()) {
468 throw std::logic_error("Invalid AST stack");
469 }
493 } 470 }
494private: 471private:
495 virtual bool accept(ast_node* node) override { 472 virtual bool accept(ast_node* node) override {
@@ -497,38 +474,36 @@ private:
497 } 474 }
498}; 475};
499 476
500template <class ...Args> class ast_sel_list : public _ast_list { 477template <bool Required, class ...Args> class ast_sel_list : public _ast_list {
501public: 478public:
502 ast_sel_list() {} 479 ast_sel_list() { }
503 480
504 ast_sel_list(const ast_sel_list<Args...>& other) { 481 ast_sel_list(const ast_sel_list& other) {
505 clear();
506 dup(other); 482 dup(other);
507 } 483 }
508 484
509 ast_sel_list<Args...>& operator=(const ast_sel_list<Args...>& other) { 485 ast_sel_list& operator=(const ast_sel_list& other) {
510 clear(); 486 clear();
511 dup(other); 487 dup(other);
512 return *this; 488 return *this;
513 } 489 }
514 490
515 /** Pops objects of type T from the stack until no more objects can be popped.
516 @param st stack.
517 */
518 virtual void construct(ast_stack &st) override { 491 virtual void construct(ast_stack &st) override {
519 while (!st.empty()) { 492 while (!st.empty()) {
520 ast_node* node = st.back(); 493 ast_node* node = st.back();
521 494 if (!ast_sel_list::accept(node)) {
522 //if the object was not not of the appropriate type, 495 if (Required && m_objects.empty()) {
523 //end the list parsing 496 throw std::logic_error("Invalid AST node");
524 if (!ast_sel_list<Args...>::accept(node)) return; 497 }
525 498 return;
499 }
526 st.pop_back(); 500 st.pop_back();
527
528 //insert the object in the list, in reverse order
529 m_objects.push_front(node); 501 m_objects.push_front(node);
530 node->retain(); 502 node->retain();
531 } 503 }
504 if (Required && m_objects.empty()) {
505 throw std::logic_error("Invalid AST stack");
506 }
532 } 507 }
533private: 508private:
534 virtual bool accept(ast_node* node) override { 509 virtual bool accept(ast_node* node) override {
@@ -583,10 +558,10 @@ ast_node* _parse(input &i, rule &g, error_list &el, void* ud);
583 @param ud user data, passed to the parse procedures. 558 @param ud user data, passed to the parse procedures.
584 @return ast nodes. 559 @return ast nodes.
585 */ 560 */
586template <class T> ast_ptr<T, false, false> parse(input &i, rule &g, error_list &el, void* ud = nullptr) { 561template <class T> ast_ptr<false, T> parse(input &i, rule &g, error_list &el, void* ud = nullptr) {
587 ast_node* node = _parse(i, g, el, ud); 562 ast_node* node = _parse(i, g, el, ud);
588 T* ast = ast_cast<T>(node); 563 T* ast = ast_cast<T>(node);
589 ast_ptr<T, false, false> ptr; 564 ast_ptr<false, T> ptr;
590 if (ast) { 565 if (ast) {
591 ast_stack st{node}; 566 ast_stack st{node};
592 ptr.construct(st); 567 ptr.construct(st);
@@ -598,6 +573,3 @@ template <class T> ast_ptr<T, false, false> parse(input &i, rule &g, error_list
598 573
599 574
600} //namespace parserlib 575} //namespace parserlib
601
602
603#endif //AST_HPP