diff options
Diffstat (limited to 'MoonParser/ast.hpp')
-rw-r--r-- | MoonParser/ast.hpp | 98 |
1 files changed, 59 insertions, 39 deletions
diff --git a/MoonParser/ast.hpp b/MoonParser/ast.hpp index 955cdc0..1d05779 100644 --- a/MoonParser/ast.hpp +++ b/MoonParser/ast.hpp | |||
@@ -36,12 +36,12 @@ int ast_type() | |||
36 | class ast_node : public input_range { | 36 | class ast_node : public input_range { |
37 | public: | 37 | public: |
38 | ///constructor. | 38 | ///constructor. |
39 | ast_node() : m_parent(0) {} | 39 | ast_node() : m_parent(nullptr) {} |
40 | 40 | ||
41 | /** copy constructor. | 41 | /** copy constructor. |
42 | @param n source object. | 42 | @param n source object. |
43 | */ | 43 | */ |
44 | ast_node(const ast_node &n) : m_parent(0) {} | 44 | ast_node(const ast_node &n) : m_parent(nullptr) {} |
45 | 45 | ||
46 | ///destructor. | 46 | ///destructor. |
47 | virtual ~ast_node() {} | 47 | virtual ~ast_node() {} |
@@ -64,9 +64,11 @@ public: | |||
64 | virtual void construct(ast_stack &st) {} | 64 | virtual void construct(ast_stack &st) {} |
65 | 65 | ||
66 | /** interface for visiting AST tree use. | 66 | /** interface for visiting AST tree use. |
67 | @param user_data vector for storing user data. | ||
68 | */ | 67 | */ |
69 | virtual void visit(void* user_data) {} | 68 | virtual bool visit(const std::function<bool (ast_node*)>& begin, |
69 | const std::function<bool (ast_node*)>& end); | ||
70 | |||
71 | virtual const char* getName() const { return "ast_node"; } | ||
70 | 72 | ||
71 | virtual int get_type() { return ast_type<ast_node>(); } | 73 | virtual int get_type() { return ast_type<ast_node>(); } |
72 | private: | 74 | private: |
@@ -96,7 +98,6 @@ bool ast_is(ast_node* node) { | |||
96 | 98 | ||
97 | class ast_member; | 99 | class ast_member; |
98 | 100 | ||
99 | |||
100 | /** type of ast member vector. | 101 | /** type of ast member vector. |
101 | */ | 102 | */ |
102 | typedef std::vector<ast_member *> ast_member_vector; | 103 | typedef std::vector<ast_member *> ast_member_vector; |
@@ -137,8 +138,12 @@ public: | |||
137 | from a node stack. | 138 | from a node stack. |
138 | @param st stack. | 139 | @param st stack. |
139 | */ | 140 | */ |
140 | virtual void construct(ast_stack &st); | 141 | virtual void construct(ast_stack &st) override; |
141 | 142 | ||
143 | virtual bool visit(const std::function<bool (ast_node*)>& begin, | ||
144 | const std::function<bool (ast_node*)>& end) override; | ||
145 | |||
146 | virtual const char* getName() const override { return "ast_container"; } | ||
142 | private: | 147 | private: |
143 | ast_member_vector m_members; | 148 | ast_member_vector m_members; |
144 | 149 | ||
@@ -177,6 +182,7 @@ public: | |||
177 | */ | 182 | */ |
178 | virtual void construct(ast_stack &st) = 0; | 183 | virtual void construct(ast_stack &st) = 0; |
179 | 184 | ||
185 | virtual int get_type() { return ast_type<ast_member>(); } | ||
180 | private: | 186 | private: |
181 | //the container this belongs to. | 187 | //the container this belongs to. |
182 | ast_container *m_container; | 188 | ast_container *m_container; |
@@ -185,6 +191,25 @@ private: | |||
185 | void _init(); | 191 | void _init(); |
186 | }; | 192 | }; |
187 | 193 | ||
194 | template<class T> | ||
195 | T* ast_cast(ast_member *member) { | ||
196 | return member && ast_type<T>() == member->get_type() ? static_cast<T*>(member) : nullptr; | ||
197 | } | ||
198 | |||
199 | class _ast_ptr : public ast_member { | ||
200 | public: | ||
201 | _ast_ptr(ast_node *node): m_ptr(node) {} | ||
202 | |||
203 | ast_node* get() const { | ||
204 | return m_ptr; | ||
205 | } | ||
206 | |||
207 | virtual int get_type() override { | ||
208 | return ast_type<_ast_ptr>(); | ||
209 | } | ||
210 | protected: | ||
211 | ast_node *m_ptr; | ||
212 | }; | ||
188 | 213 | ||
189 | /** pointer to an AST object. | 214 | /** pointer to an AST object. |
190 | It assumes ownership of the object. | 215 | It assumes ownership of the object. |
@@ -192,12 +217,12 @@ private: | |||
192 | @tparam T type of object to control. | 217 | @tparam T type of object to control. |
193 | @tparam OPT if true, the object becomes optional. | 218 | @tparam OPT if true, the object becomes optional. |
194 | */ | 219 | */ |
195 | template <class T, bool OPT = false> class ast_ptr : public ast_member { | 220 | template <class T, bool OPT = false> class ast_ptr : public _ast_ptr { |
196 | public: | 221 | public: |
197 | /** the default constructor. | 222 | /** the default constructor. |
198 | @param obj object. | 223 | @param obj object. |
199 | */ | 224 | */ |
200 | ast_ptr(T *obj = 0) : m_ptr(obj) { | 225 | ast_ptr(T *obj = nullptr) : _ast_ptr(obj) { |
201 | _set_parent(); | 226 | _set_parent(); |
202 | } | 227 | } |
203 | 228 | ||
@@ -206,7 +231,7 @@ public: | |||
206 | @param src source object. | 231 | @param src source object. |
207 | */ | 232 | */ |
208 | ast_ptr(const ast_ptr<T, OPT> &src) : | 233 | ast_ptr(const ast_ptr<T, OPT> &src) : |
209 | m_ptr(src.m_ptr ? new T(*src.m_ptr) : 0) | 234 | _ast_ptr(src.m_ptr ? new T(*src.m_ptr) : nullptr) |
210 | { | 235 | { |
211 | _set_parent(); | 236 | _set_parent(); |
212 | } | 237 | } |
@@ -224,7 +249,7 @@ public: | |||
224 | */ | 249 | */ |
225 | ast_ptr<T, OPT> &operator = (const T *obj) { | 250 | ast_ptr<T, OPT> &operator = (const T *obj) { |
226 | delete m_ptr; | 251 | delete m_ptr; |
227 | m_ptr = obj ? new T(*obj) : 0; | 252 | m_ptr = obj ? new T(*obj) : nullptr; |
228 | _set_parent(); | 253 | _set_parent(); |
229 | return *this; | 254 | return *this; |
230 | } | 255 | } |
@@ -236,7 +261,7 @@ public: | |||
236 | */ | 261 | */ |
237 | ast_ptr<T, OPT> &operator = (const ast_ptr<T, OPT> &src) { | 262 | ast_ptr<T, OPT> &operator = (const ast_ptr<T, OPT> &src) { |
238 | delete m_ptr; | 263 | delete m_ptr; |
239 | m_ptr = src.m_ptr ? new T(*src.m_ptr) : 0; | 264 | m_ptr = src.m_ptr ? new T(*src.m_ptr) : nullptr; |
240 | _set_parent(); | 265 | _set_parent(); |
241 | return *this; | 266 | return *this; |
242 | } | 267 | } |
@@ -245,14 +270,14 @@ public: | |||
245 | @return the underlying ptr value. | 270 | @return the underlying ptr value. |
246 | */ | 271 | */ |
247 | T *get() const { | 272 | T *get() const { |
248 | return m_ptr; | 273 | return static_cast<T*>(m_ptr); |
249 | } | 274 | } |
250 | 275 | ||
251 | /** auto conversion to the underlying object ptr. | 276 | /** auto conversion to the underlying object ptr. |
252 | @return the underlying ptr value. | 277 | @return the underlying ptr value. |
253 | */ | 278 | */ |
254 | operator T *() const { | 279 | operator T *() const { |
255 | return m_ptr; | 280 | return static_cast<T*>(m_ptr); |
256 | } | 281 | } |
257 | 282 | ||
258 | /** member access. | 283 | /** member access. |
@@ -299,25 +324,21 @@ public: | |||
299 | m_ptr = obj; | 324 | m_ptr = obj; |
300 | _set_parent(); | 325 | _set_parent(); |
301 | } | 326 | } |
302 | |||
303 | private: | 327 | private: |
304 | //ptr | ||
305 | T *m_ptr; | ||
306 | |||
307 | //set parent of object | 328 | //set parent of object |
308 | void _set_parent() { | 329 | void _set_parent() { |
309 | if (m_ptr) m_ptr->m_parent = container(); | 330 | if (m_ptr) m_ptr->m_parent = container(); |
310 | } | 331 | } |
311 | }; | 332 | }; |
312 | 333 | ||
313 | template <class ...Args> class ast_choice : public ast_member { | 334 | template <class ...Args> class ast_choice : public _ast_ptr { |
314 | public: | 335 | public: |
315 | ast_choice(ast_node *obj = 0) : m_ptr(obj) { | 336 | ast_choice(ast_node *obj = nullptr) : _ast_ptr(obj) { |
316 | _set_parent(); | 337 | _set_parent(); |
317 | } | 338 | } |
318 | 339 | ||
319 | ast_choice(const ast_choice<Args...> &src) : | 340 | ast_choice(const ast_choice<Args...> &src) : |
320 | m_ptr(src.m_ptr ? new ast_node(*src.m_ptr) : 0) | 341 | _ast_ptr(src.m_ptr ? new ast_node(*src.m_ptr) : nullptr) |
321 | { | 342 | { |
322 | _set_parent(); | 343 | _set_parent(); |
323 | } | 344 | } |
@@ -328,22 +349,18 @@ public: | |||
328 | 349 | ||
329 | ast_choice<Args...> &operator = (const ast_node *obj) { | 350 | ast_choice<Args...> &operator = (const ast_node *obj) { |
330 | delete m_ptr; | 351 | delete m_ptr; |
331 | m_ptr = obj ? new ast_node(*obj) : 0; | 352 | m_ptr = obj ? new ast_node(*obj) : nullptr; |
332 | _set_parent(); | 353 | _set_parent(); |
333 | return *this; | 354 | return *this; |
334 | } | 355 | } |
335 | 356 | ||
336 | ast_choice<Args...> &operator = (const ast_choice<Args...> &src) { | 357 | ast_choice<Args...> &operator = (const ast_choice<Args...> &src) { |
337 | delete m_ptr; | 358 | delete m_ptr; |
338 | m_ptr = src.m_ptr ? new ast_node(*src.m_ptr) : 0; | 359 | m_ptr = src.m_ptr ? new ast_node(*src.m_ptr) : nullptr; |
339 | _set_parent(); | 360 | _set_parent(); |
340 | return *this; | 361 | return *this; |
341 | } | 362 | } |
342 | 363 | ||
343 | ast_node *get() const { | ||
344 | return m_ptr; | ||
345 | } | ||
346 | |||
347 | operator ast_node *() const { | 364 | operator ast_node *() const { |
348 | return m_ptr; | 365 | return m_ptr; |
349 | } | 366 | } |
@@ -372,26 +389,33 @@ public: | |||
372 | m_ptr = obj; | 389 | m_ptr = obj; |
373 | _set_parent(); | 390 | _set_parent(); |
374 | } | 391 | } |
375 | |||
376 | private: | 392 | private: |
377 | //ptr | ||
378 | ast_node *m_ptr; | ||
379 | |||
380 | void _set_parent() { | 393 | void _set_parent() { |
381 | if (m_ptr) m_ptr->m_parent = container(); | 394 | if (m_ptr) m_ptr->m_parent = container(); |
382 | } | 395 | } |
383 | }; | 396 | }; |
384 | 397 | ||
398 | class _ast_list : public ast_member { | ||
399 | public: | ||
400 | ///list type. | ||
401 | typedef std::list<ast_node *> container; | ||
402 | |||
403 | virtual int get_type() override { return ast_type<_ast_list>(); } | ||
404 | |||
405 | const container &objects() const { | ||
406 | return m_objects; | ||
407 | } | ||
408 | protected: | ||
409 | container m_objects; | ||
410 | }; | ||
411 | |||
385 | /** A list of objects. | 412 | /** A list of objects. |
386 | It pops objects of the given type from the ast stack, until no more objects can be popped. | 413 | It pops objects of the given type from the ast stack, until no more objects can be popped. |
387 | It assumes ownership of objects. | 414 | It assumes ownership of objects. |
388 | @tparam T type of object to control. | 415 | @tparam T type of object to control. |
389 | */ | 416 | */ |
390 | template <class T> class ast_list : public ast_member { | 417 | template <class T> class ast_list : public _ast_list { |
391 | public: | 418 | public: |
392 | ///list type. | ||
393 | typedef std::list<T *> container; | ||
394 | |||
395 | ///the default constructor. | 419 | ///the default constructor. |
396 | ast_list() {} | 420 | ast_list() {} |
397 | 421 | ||
@@ -430,7 +454,7 @@ public: | |||
430 | /** Pops objects of type T from the stack until no more objects can be popped. | 454 | /** Pops objects of type T from the stack until no more objects can be popped. |
431 | @param st stack. | 455 | @param st stack. |
432 | */ | 456 | */ |
433 | virtual void construct(ast_stack &st) { | 457 | virtual void construct(ast_stack &st) override { |
434 | for(;;) { | 458 | for(;;) { |
435 | //if the stack is empty | 459 | //if the stack is empty |
436 | if (st.empty()) break; | 460 | if (st.empty()) break; |
@@ -455,11 +479,7 @@ public: | |||
455 | obj->m_parent = ast_member::container(); | 479 | obj->m_parent = ast_member::container(); |
456 | } | 480 | } |
457 | } | 481 | } |
458 | |||
459 | private: | 482 | private: |
460 | //objects | ||
461 | container m_objects; | ||
462 | |||
463 | //deletes the objects of this list. | 483 | //deletes the objects of this list. |
464 | void _clear() { | 484 | void _clear() { |
465 | while (!m_objects.empty()) { | 485 | while (!m_objects.empty()) { |