aboutsummaryrefslogtreecommitdiff
path: root/MoonParser/ast.hpp
diff options
context:
space:
mode:
authorLi Jin <dragon-fly@qq.com>2019-09-12 16:12:20 +0800
committerLi Jin <dragon-fly@qq.com>2019-09-12 16:12:20 +0800
commit50353c1456324e7bd3c130fceaf400aed7880a41 (patch)
tree0afe5823040dc9fc9ab39a9d7f4af647c061d7c1 /MoonParser/ast.hpp
parent4e6f4e8124316866a08f9ddf3322fde87abc3c21 (diff)
downloadyuescript-50353c1456324e7bd3c130fceaf400aed7880a41.tar.gz
yuescript-50353c1456324e7bd3c130fceaf400aed7880a41.tar.bz2
yuescript-50353c1456324e7bd3c130fceaf400aed7880a41.zip
spec/assign.moon and spec/bubbling.moon compiled
Diffstat (limited to 'MoonParser/ast.hpp')
-rw-r--r--MoonParser/ast.hpp471
1 files changed, 196 insertions, 275 deletions
diff --git a/MoonParser/ast.hpp b/MoonParser/ast.hpp
index 4d52dfc..982eea8 100644
--- a/MoonParser/ast.hpp
+++ b/MoonParser/ast.hpp
@@ -13,14 +13,14 @@ namespace parserlib {
13 13
14 14
15class ast_node; 15class ast_node;
16template <class T, bool OPT> class ast_ptr; 16template <class T, bool OPT, bool MEM> class ast_ptr;
17template <class T> class ast_list; 17template <class T> class ast_list;
18template <class T> class ast; 18template <class T> class ast;
19 19
20 20
21/** type of AST node stack. 21/** type of AST node stack.
22 */ 22 */
23typedef std::vector<ast_node *> ast_stack; 23typedef std::vector<ast_node*> ast_stack;
24 24
25extern int ast_type_id; 25extern int ast_type_id;
26 26
@@ -41,33 +41,24 @@ enum class traversal {
41 */ 41 */
42class ast_node : public input_range { 42class ast_node : public input_range {
43public: 43public:
44 ///constructor. 44 ast_node() : _ref(0) {}
45 ast_node() : m_parent(nullptr) {} 45
46 46 void retain() {
47 /** copy constructor. 47 ++_ref;
48 @param n source object. 48 }
49 */ 49
50 ast_node(const ast_node &n) : m_parent(nullptr) {} 50 void release() {
51 51 --_ref;
52 ///destructor. 52 if (_ref == 0) {
53 virtual ~ast_node() {} 53 delete this;
54 54 }
55 /** assignment operator. 55 }
56 @param n source object. 56
57 @return reference to this.
58 */
59 ast_node &operator = (const ast_node &n) { return *this; }
60
61 /** get the parent node.
62 @return the parent node, if there is one.
63 */
64 ast_node *parent() const { return m_parent; }
65
66 /** interface for filling the contents of the node 57 /** interface for filling the contents of the node
67 from a node stack. 58 from a node stack.
68 @param st stack. 59 @param st stack.
69 */ 60 */
70 virtual void construct(ast_stack &st) {} 61 virtual void construct(ast_stack& st) {}
71 62
72 /** interface for visiting AST tree use. 63 /** interface for visiting AST tree use.
73 */ 64 */
@@ -81,7 +72,11 @@ public:
81 72
82 virtual ast_node* getChild(int) const { return nullptr; } 73 virtual ast_node* getChild(int) const { return nullptr; }
83 74
84 virtual int getChildCount() const { return 0; } 75 virtual size_t getChildCount() const { return 0; }
76
77 virtual ast_node* getFirstChild() const { return nullptr; }
78
79 virtual ast_node* getLastChild() const { return nullptr; }
85 80
86 virtual size_t getId() const { return "ast_node"_id; } 81 virtual size_t getId() const { return "ast_node"_id; }
87 82
@@ -89,10 +84,8 @@ public:
89 84
90 virtual int get_type() { return ast_type<ast_node>(); } 85 virtual int get_type() { return ast_type<ast_node>(); }
91private: 86private:
92 //parent 87 int _ref;
93 ast_node *m_parent; 88 template <class T, bool OPT, bool MEM> friend class ast_ptr;
94
95 template <class T, bool OPT> friend class ast_ptr;
96 template <class ...Args> friend class ast_choice; 89 template <class ...Args> friend class ast_choice;
97 template <class T> friend class ast_list; 90 template <class T> friend class ast_list;
98 template <class T> friend class ast; 91 template <class T> friend class ast;
@@ -117,7 +110,7 @@ class ast_member;
117 110
118/** type of ast member vector. 111/** type of ast member vector.
119 */ 112 */
120typedef std::vector<ast_member *> ast_member_vector; 113typedef std::vector<ast_member*> ast_member_vector;
121 114
122 115
123/** base class for AST nodes with children. 116/** base class for AST nodes with children.
@@ -128,25 +121,10 @@ public:
128 */ 121 */
129 ast_container(); 122 ast_container();
130 123
131 /** sets the container under construction to be this.
132 Members are not copied.
133 @param src source object.
134 */
135 ast_container(const ast_container &src);
136
137 /** the assignment operator.
138 The members are not copied.
139 @param src source object.
140 @return reference to this.
141 */
142 ast_container &operator = (const ast_container &src) {
143 return *this;
144 }
145
146 /** returns the vector of AST members. 124 /** returns the vector of AST members.
147 @return the vector of AST members. 125 @return the vector of AST members.
148 */ 126 */
149 const ast_member_vector &members() const { 127 const ast_member_vector& members() const {
150 return m_members; 128 return m_members;
151 } 129 }
152 130
@@ -155,7 +133,7 @@ public:
155 from a node stack. 133 from a node stack.
156 @param st stack. 134 @param st stack.
157 */ 135 */
158 virtual void construct(ast_stack &st) override; 136 virtual void construct(ast_stack& st) override;
159 137
160 virtual ast_node* getByPath(std::initializer_list<std::size_t> paths) override; 138 virtual ast_node* getByPath(std::initializer_list<std::size_t> paths) override;
161 139
@@ -167,7 +145,11 @@ public:
167 145
168 virtual ast_node* getChild(int index) const override; 146 virtual ast_node* getChild(int index) const override;
169 147
170 virtual int getChildCount() const override; 148 virtual size_t getChildCount() const override;
149
150 virtual ast_node* getFirstChild() const override;
151
152 virtual ast_node* getLastChild() const override;
171 153
172 virtual size_t getId() const override { return "ast_container"_id; } 154 virtual size_t getId() const override { return "ast_container"_id; }
173 155
@@ -185,58 +167,76 @@ class ast_member {
185public: 167public:
186 /** automatically registers itself to the container under construction. 168 /** automatically registers itself to the container under construction.
187 */ 169 */
188 ast_member() { _init(); } 170 ast_member(bool is_member) {
171 if (is_member) add_to_owner();
172 }
189 173
190 /** automatically registers itself to the container under construction. 174 virtual ~ast_member() {}
191 @param src source object.
192 */
193 ast_member(const ast_member &src) { _init(); }
194
195 /** the assignment operator.
196 @param src source object.
197 @return reference to this.
198 */
199 ast_member &operator = (const ast_member &src) {
200 return *this;
201 }
202
203 /** returns the container this belongs to.
204 @return the container this belongs to.
205 */
206 ast_container *container() const { return m_container; }
207 175
208 /** interface for filling the the member from a node stack. 176 /** interface for filling the the member from a node stack.
209 @param st stack. 177 @param st stack.
210 */ 178 */
211 virtual void construct(ast_stack &st) = 0; 179 virtual void construct(ast_stack& st) = 0;
180
181 virtual bool accept(ast_node* node) = 0;
212 182
213 virtual int get_type() { return ast_type<ast_member>(); } 183 virtual int get_type() { return ast_type<ast_member>(); }
214private: 184private:
215 //the container this belongs to.
216 ast_container *m_container;
217
218 //register the AST member to the current container. 185 //register the AST member to the current container.
219 void _init(); 186 void add_to_owner();
220}; 187};
221 188
222template<class T> 189template<class T>
223T* ast_cast(ast_member *member) { 190T* ast_cast(ast_member* member) {
224 return member && ast_type<T>() == member->get_type() ? static_cast<T*>(member) : nullptr; 191 return member && ast_type<T>() == member->get_type() ? static_cast<T*>(member) : nullptr;
225} 192}
226 193
227class _ast_ptr : public ast_member { 194class _ast_ptr : public ast_member {
228public: 195public:
229 _ast_ptr(ast_node *node): m_ptr(node) {} 196 _ast_ptr(ast_node* node, bool is_member) : ast_member(is_member), m_ptr(node) {
197 if (node) node->retain();
198 }
199
200 virtual ~_ast_ptr() {
201 if (m_ptr) {
202 m_ptr->release();
203 m_ptr = nullptr;
204 }
205 }
230 206
231 ast_node* get() const { 207 ast_node* get() const {
232 return m_ptr; 208 return m_ptr;
233 } 209 }
234 210
211 template <class T>
212 T* as() const {
213 return ast_cast<T>(m_ptr);
214 }
215
216 template <class T>
217 T* to() const {
218 assert(m_ptr->getId() == ast_type<T>());
219 return static_cast<T*>(m_ptr);
220 }
221
222 void set(ast_node* node) {
223 if (node == m_ptr) return;
224 else if (!node) {
225 if (m_ptr) m_ptr->release();
226 m_ptr = nullptr;
227 }
228 else if (accept(node)) {
229 if (m_ptr) m_ptr->release();
230 m_ptr = node;
231 node->retain();
232 }
233 }
234
235 virtual int get_type() override { 235 virtual int get_type() override {
236 return ast_type<_ast_ptr>(); 236 return ast_type<_ast_ptr>();
237 } 237 }
238protected: 238protected:
239 ast_node *m_ptr; 239 ast_node* m_ptr;
240}; 240};
241 241
242/** pointer to an AST object. 242/** pointer to an AST object.
@@ -245,75 +245,37 @@ protected:
245 @tparam T type of object to control. 245 @tparam T type of object to control.
246 @tparam OPT if true, the object becomes optional. 246 @tparam OPT if true, the object becomes optional.
247 */ 247 */
248template <class T, bool OPT = false> class ast_ptr : public _ast_ptr { 248template <class T, bool OPT = false, bool MEM = true> class ast_ptr : public _ast_ptr {
249public: 249public:
250 /** the default constructor. 250 ast_ptr(T* node = nullptr) : _ast_ptr(node, MEM) {}
251 @param obj object.
252 */
253 ast_ptr(T *obj = nullptr) : _ast_ptr(obj) {
254 _set_parent();
255 }
256
257 /** the copy constructor.
258 It duplicates the underlying object.
259 @param src source object.
260 */
261 ast_ptr(const ast_ptr<T, OPT> &src) :
262 _ast_ptr(src.m_ptr ? new T(*src.m_ptr) : nullptr)
263 {
264 _set_parent();
265 }
266 251
267 /** deletes the underlying object. 252 ast_ptr(const ast_ptr<T, OPT, MEM>& other) : _ast_ptr(other.get(), MEM) {}
268 */
269 ~ast_ptr() {
270 delete m_ptr;
271 }
272 253
273 /** copies the given object. 254 ast_ptr<T, OPT, MEM>& operator=(const ast_ptr<T, OPT, MEM>& other) {
274 The old object is deleted. 255 set(other.get());
275 @param obj new object. 256 return *this;
276 @return reference to this. 257 }
277 */
278 ast_ptr<T, OPT> &operator = (const T *obj) {
279 delete m_ptr;
280 m_ptr = obj ? new T(*obj) : nullptr;
281 _set_parent();
282 return *this;
283 }
284
285 /** copies the underlying object.
286 The old object is deleted.
287 @param src source object.
288 @return reference to this.
289 */
290 ast_ptr<T, OPT> &operator = (const ast_ptr<T, OPT> &src) {
291 delete m_ptr;
292 m_ptr = src.m_ptr ? new T(*src.m_ptr) : nullptr;
293 _set_parent();
294 return *this;
295 }
296 258
297 /** gets the underlying ptr value. 259 /** gets the underlying ptr value.
298 @return the underlying ptr value. 260 @return the underlying ptr value.
299 */ 261 */
300 T *get() const { 262 T* get() const {
301 return static_cast<T*>(m_ptr); 263 return static_cast<T*>(m_ptr);
302 } 264 }
303 265
304 /** auto conversion to the underlying object ptr. 266 /** auto conversion to the underlying object ptr.
305 @return the underlying ptr value. 267 @return the underlying ptr value.
306 */ 268 */
307 operator T *() const { 269 operator T*() const {
308 return static_cast<T*>(m_ptr); 270 return static_cast<T*>(m_ptr);
309 } 271 }
310 272
311 /** member access. 273 /** member access.
312 @return the underlying ptr value. 274 @return the underlying ptr value.
313 */ 275 */
314 T *operator ->() const { 276 T* operator->() const {
315 assert(m_ptr); 277 assert(m_ptr);
316 return m_ptr; 278 return static_cast<T*>(m_ptr);
317 } 279 }
318 280
319 /** Pops a node from the stack. 281 /** Pops a node from the stack.
@@ -321,118 +283,120 @@ public:
321 @exception std::logic_error thrown if the node is not of the appropriate type; 283 @exception std::logic_error thrown if the node is not of the appropriate type;
322 thrown only if OPT == false or if the stack is empty. 284 thrown only if OPT == false or if the stack is empty.
323 */ 285 */
324 virtual void construct(ast_stack &st) { 286 virtual void construct(ast_stack& st) override {
325 //check the stack node 287 //check the stack node
326 if (st.empty()) { 288 if (st.empty()) {
327 if (OPT) return; 289 if (OPT) return;
328 else throw std::logic_error("invalid AST stack"); 290 else throw std::logic_error("invalid AST stack");
329 } 291 }
330 292
331 //get the node 293 ast_node* node = st.back();
332 ast_node *node = st.back(); 294
333 295 if (!ast_ptr::accept(node)) {
334 //get the object 296 //if the object is optional, simply return
335 T *obj = std::is_same<T, ast_node>() ? static_cast<T*>(node) : ast_cast<T>(node); 297 if (OPT) {
336 298 return;
337 //if the object is optional, simply return 299 } else { //else if the object is mandatory, throw an exception
338 if (OPT) { 300 throw std::logic_error("invalid AST node");
339 if (!obj) return; 301 }
340 } 302 }
341 303
342 //else if the object is mandatory, throw an exception
343 else {
344 if (!obj) throw std::logic_error("invalid AST node");
345 }
346
347 //pop the node from the stack
348 st.pop_back(); 304 st.pop_back();
349 305
350 //set the new object 306 m_ptr = node;
351 delete m_ptr; 307 node->retain();
352 m_ptr = obj;
353 _set_parent();
354 } 308 }
355private: 309private:
356 //set parent of object 310 virtual bool accept(ast_node* node) override {
357 void _set_parent() { 311 return node && (std::is_same<ast_node,T>() || ast_type<T>() == node->get_type());
358 if (m_ptr) m_ptr->m_parent = container(); 312 }
359 }
360}; 313};
361 314
315template<class T>
316inline ast_ptr<T, false, false> new_ptr() {
317 return ast_ptr<T, false, false>(new T);
318}
319
362template <class ...Args> class ast_choice : public _ast_ptr { 320template <class ...Args> class ast_choice : public _ast_ptr {
363public: 321public:
364 ast_choice(ast_node *obj = nullptr) : _ast_ptr(obj) { 322 ast_choice() : _ast_ptr(nullptr, true) {}
365 _set_parent();
366 }
367
368 ast_choice(const ast_choice<Args...> &src) :
369 _ast_ptr(src.m_ptr ? new ast_node(*src.m_ptr) : nullptr)
370 {
371 _set_parent();
372 }
373 323
374 ~ast_choice() { 324 ast_choice(const ast_choice<Args...>& other) : _ast_ptr(other.get(), true) {}
375 delete m_ptr;
376 }
377
378 ast_choice<Args...> &operator = (const ast_node *obj) {
379 delete m_ptr;
380 m_ptr = obj ? new ast_node(*obj) : nullptr;
381 _set_parent();
382 return *this;
383 }
384 325
385 ast_choice<Args...> &operator = (const ast_choice<Args...> &src) { 326 ast_choice<Args...>& operator=(const ast_choice<Args...>& other) {
386 delete m_ptr; 327 set(other.get());
387 m_ptr = src.m_ptr ? new ast_node(*src.m_ptr) : nullptr; 328 return *this;
388 _set_parent(); 329 }
389 return *this;
390 }
391 330
392 operator ast_node *() const { 331 operator ast_node*() const {
393 return m_ptr; 332 return m_ptr;
394 } 333 }
395 334
396 ast_node *operator ->() const { 335 ast_node* operator->() const {
397 assert(m_ptr); 336 assert(m_ptr);
398 return m_ptr; 337 return m_ptr;
399 } 338 }
400 339
401 virtual void construct(ast_stack &st) { 340 virtual void construct(ast_stack& st) override {
402 if (st.empty()) { 341 if (st.empty()) {
403 throw std::logic_error("invalid AST stack"); 342 throw std::logic_error("invalid AST stack");
404 } 343 }
405 344
406 ast_node *node = st.back(); 345 ast_node* node = st.back();
407 ast_node *obj = nullptr;
408
409 using swallow = bool[];
410 (void)swallow{obj || (obj = std::is_same<Args, ast_node>() ? node : ast_cast<Args>(node))...};
411 346
412 if (!obj) throw std::logic_error("invalid AST node"); 347 if (!ast_choice::accept(node)) throw std::logic_error("invalid AST node");
413 348
414 st.pop_back(); 349 st.pop_back();
415 350
416 delete m_ptr; 351 m_ptr = node;
417 m_ptr = obj; 352 node->retain();
418 _set_parent();
419 } 353 }
420private: 354private:
421 void _set_parent() { 355 virtual bool accept(ast_node* node) override {
422 if (m_ptr) m_ptr->m_parent = container(); 356 if (!node) return false;
423 } 357 using swallow = bool[];
358 bool* result = nullptr;
359 (void)swallow{result || (result = ast_type<Args>() == node->get_type())...};
360 return result;
361 }
424}; 362};
425 363
426class _ast_list : public ast_member { 364class _ast_list : public ast_member {
427public: 365public:
428 ///list type. 366 typedef std::list<ast_node*> container;
429 typedef std::list<ast_node *> container;
430 367
431 virtual int get_type() override { return ast_type<_ast_list>(); } 368 _ast_list() : ast_member(true) {}
369
370 ~_ast_list() {
371 clear();
372 }
373
374 void add(ast_node* node) {
375 if (accept(node)) {
376 m_objects.push_back(node);
377 node->retain();
378 }
379 }
432 380
433 const container &objects() const { 381 const container& objects() const {
434 return m_objects; 382 return m_objects;
435 } 383 }
384
385 void clear() {
386 for(ast_node* obj : m_objects) {
387 if (obj) obj->release();
388 }
389 m_objects.clear();
390 }
391
392 void dup(const _ast_list& src) {
393 for(ast_node* obj : src.m_objects) {
394 m_objects.push_back(obj);
395 obj->retain();
396 }
397 }
398
399 virtual int get_type() override { return ast_type<_ast_list>(); }
436protected: 400protected:
437 container m_objects; 401 container m_objects;
438}; 402};
@@ -447,86 +411,39 @@ public:
447 ///the default constructor. 411 ///the default constructor.
448 ast_list() {} 412 ast_list() {}
449 413
450 /** duplicates the objects of the given list. 414 ast_list(const ast_list<T>& other) {
451 @param src source object. 415 clear();
452 */ 416 dup(other);
453 ast_list(const ast_list<T> &src) { 417 }
454 _dup(src);
455 }
456
457 /** deletes the objects.
458 */
459 ~ast_list() {
460 _clear();
461 }
462
463 /** deletes the objects of this list and duplicates the given one.
464 @param src source object.
465 @return reference to this.
466 */
467 ast_list<T> &operator = (const ast_list<T> &src) {
468 if (&src != this) {
469 _clear();
470 _dup(src);
471 }
472 return *this;
473 }
474 418
475 /** returns the container of objects. 419 ast_list<T>& operator=(const ast_list<T>& other) {
476 @return the container of objects. 420 clear();
477 */ 421 dup(other);
478 const container &objects() const { 422 return *this;
479 return m_objects; 423 }
480 }
481 424
482 /** Pops objects of type T from the stack until no more objects can be popped. 425 /** Pops objects of type T from the stack until no more objects can be popped.
483 @param st stack. 426 @param st stack.
484 */ 427 */
485 virtual void construct(ast_stack &st) override { 428 virtual void construct(ast_stack &st) override {
486 for(;;) { 429 while (!st.empty()) {
487 //if the stack is empty 430 ast_node* node = st.back();
488 if (st.empty()) break; 431
489
490 //get the node
491 ast_node *node = st.back();
492
493 //get the object
494 T *obj = std::is_same<T, ast_node>() ? static_cast<T*>(node) : ast_cast<T>(node);
495
496 //if the object was not not of the appropriate type, 432 //if the object was not not of the appropriate type,
497 //end the list parsing 433 //end the list parsing
498 if (!obj) return; 434 if (!ast_list::accept(node)) return;
499 435
500 //remove the node from the stack
501 st.pop_back(); 436 st.pop_back();
502 437
503 //insert the object in the list, in reverse order 438 //insert the object in the list, in reverse order
504 m_objects.push_front(obj); 439 m_objects.push_front(node);
505 440 node->retain();
506 //set the object's parent
507 obj->m_parent = ast_member::container();
508 } 441 }
509 } 442 }
510private: 443private:
511 //deletes the objects of this list. 444 virtual bool accept(ast_node* node) override {
512 void _clear() { 445 return node && (std::is_same<ast_node,T>() || ast_type<T>() == node->get_type());
513 while (!m_objects.empty()) { 446 }
514 delete m_objects.back();
515 m_objects.pop_back();
516 }
517 }
518
519 //duplicate the given list.
520 void _dup(const ast_list<T> &src) {
521 for(typename container::const_iterator it = src.m_objects.begin();
522 it != src.m_objects.end();
523 ++it)
524 {
525 T *obj = new T(*it);
526 m_objects.push_back(obj);
527 obj->m_parent = ast_member::container();
528 }
529 }
530}; 447};
531 448
532 449
@@ -538,15 +455,15 @@ public:
538 /** constructor. 455 /** constructor.
539 @param r rule to attach the AST function to. 456 @param r rule to attach the AST function to.
540 */ 457 */
541 ast(rule &r) { 458 ast(rule& r) {
542 r.set_parse_proc(&_parse_proc); 459 r.set_parse_proc(&_parse_proc);
543 } 460 }
544 461
545private: 462private:
546 //parse proc 463 //parse proc
547 static void _parse_proc(const pos &b, const pos &e, void *d) { 464 static void _parse_proc(const pos& b, const pos& e, void* d) {
548 ast_stack *st = reinterpret_cast<ast_stack *>(d); 465 ast_stack* st = reinterpret_cast<ast_stack*>(d);
549 T *obj = new T; 466 T* obj = new T;
550 obj->m_begin = b; 467 obj->m_begin = b;
551 obj->m_end = e; 468 obj->m_end = e;
552 obj->construct(*st); 469 obj->construct(*st);
@@ -563,23 +480,27 @@ private:
563 @return pointer to ast node created, or null if there was an error. 480 @return pointer to ast node created, or null if there was an error.
564 The return object must be deleted by the caller. 481 The return object must be deleted by the caller.
565 */ 482 */
566ast_node *parse(input &i, rule &g, error_list &el, void* ud); 483ast_node* _parse(input &i, rule &g, error_list &el, void* ud);
567 484
568 485
569/** parses the given input. 486/** parses the given input.
570 @param i input. 487 @param i input.
571 @param g root rule of grammar. 488 @param g root rule of grammar.
572 @param el list of errors. 489 @param el list of errors.
573 @param ast result pointer to created ast.
574 @param ud user data, passed to the parse procedures. 490 @param ud user data, passed to the parse procedures.
575 @return true on success, false on error. 491 @return ast nodes.
576 */ 492 */
577template <class T> bool parse(input &i, rule &g, error_list &el, T *&ast, void* ud = nullptr) { 493template <class T> ast_ptr<T, false, false> parse(input &i, rule &g, error_list &el, void* ud = nullptr) {
578 ast_node *node = parse(i, g, el, ud); 494 ast_node* node = _parse(i, g, el, ud);
579 ast = ast_cast<T>(node); 495 T* ast = ast_cast<T>(node);
580 if (ast) return true; 496 ast_ptr<T, false, false> ptr;
581 delete node; 497 if (ast) {
582 return false; 498 ast_stack st{node};
499 ptr.construct(st);
500 } else if (node) {
501 delete node;
502 }
503 return ptr;
583} 504}
584 505
585 506