diff options
| author | Li Jin <dragon-fly@qq.com> | 2017-07-16 23:47:58 +0800 |
|---|---|---|
| committer | Li Jin <dragon-fly@qq.com> | 2017-07-16 23:47:58 +0800 |
| commit | 21328c2299eebc03c13478d7d214f9ed58d9688e (patch) | |
| tree | acf359dd833a4d0b5dfefaf4e2bed7b29dad4974 | |
| parent | 9e63302e5906d53d9f39f64c549b9aa7e806b669 (diff) | |
| download | yuescript-21328c2299eebc03c13478d7d214f9ed58d9688e.tar.gz yuescript-21328c2299eebc03c13478d7d214f9ed58d9688e.tar.bz2 yuescript-21328c2299eebc03c13478d7d214f9ed58d9688e.zip | |
remove uses of dynamic_cast.
| -rw-r--r-- | MoonParser/ast.cpp | 2 | ||||
| -rw-r--r-- | MoonParser/ast.hpp | 24 | ||||
| -rw-r--r-- | MoonParser/main.cpp | 9 |
3 files changed, 27 insertions, 8 deletions
diff --git a/MoonParser/ast.cpp b/MoonParser/ast.cpp index 916fdd7..090f5ee 100644 --- a/MoonParser/ast.cpp +++ b/MoonParser/ast.cpp | |||
| @@ -8,6 +8,8 @@ namespace parserlib { | |||
| 8 | //current AST container. | 8 | //current AST container. |
| 9 | static ast_container *_current = 0; | 9 | static ast_container *_current = 0; |
| 10 | 10 | ||
| 11 | int ast_type_id = 0; | ||
| 12 | |||
| 11 | 13 | ||
| 12 | /** sets the container under construction to be this. | 14 | /** sets the container under construction to be this. |
| 13 | */ | 15 | */ |
diff --git a/MoonParser/ast.hpp b/MoonParser/ast.hpp index 664c8af..01e2350 100644 --- a/MoonParser/ast.hpp +++ b/MoonParser/ast.hpp | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | #include <cassert> | 5 | #include <cassert> |
| 6 | #include <list> | 6 | #include <list> |
| 7 | #include <stdexcept> | 7 | #include <stdexcept> |
| 8 | #include <type_traits> | ||
| 8 | #include "parser.hpp" | 9 | #include "parser.hpp" |
| 9 | 10 | ||
| 10 | 11 | ||
| @@ -21,6 +22,14 @@ template <class T> class ast; | |||
| 21 | */ | 22 | */ |
| 22 | typedef std::vector<ast_node *> ast_stack; | 23 | typedef std::vector<ast_node *> ast_stack; |
| 23 | 24 | ||
| 25 | extern int ast_type_id; | ||
| 26 | |||
| 27 | template<class T> | ||
| 28 | int ast_type() | ||
| 29 | { | ||
| 30 | static int type = ast_type_id++; | ||
| 31 | return type; | ||
| 32 | } | ||
| 24 | 33 | ||
| 25 | /** Base class for AST nodes. | 34 | /** Base class for AST nodes. |
| 26 | */ | 35 | */ |
| @@ -58,6 +67,8 @@ public: | |||
| 58 | @param user_data vector for storing user data. | 67 | @param user_data vector for storing user data. |
| 59 | */ | 68 | */ |
| 60 | virtual void visit(void* user_data) {} | 69 | virtual void visit(void* user_data) {} |
| 70 | |||
| 71 | virtual int get_type() { return ast_type<ast_node>(); } | ||
| 61 | private: | 72 | private: |
| 62 | //parent | 73 | //parent |
| 63 | ast_node *m_parent; | 74 | ast_node *m_parent; |
| @@ -68,6 +79,11 @@ private: | |||
| 68 | template <class T> friend class ast; | 79 | template <class T> friend class ast; |
| 69 | }; | 80 | }; |
| 70 | 81 | ||
| 82 | template<class T> | ||
| 83 | T* ast_cast(ast_node *node) | ||
| 84 | { | ||
| 85 | return ast_type<T>() == node->get_type() ? static_cast<T*>(node) : nullptr; | ||
| 86 | } | ||
| 71 | 87 | ||
| 72 | class ast_member; | 88 | class ast_member; |
| 73 | 89 | ||
| @@ -254,7 +270,7 @@ public: | |||
| 254 | ast_node *node = st.back(); | 270 | ast_node *node = st.back(); |
| 255 | 271 | ||
| 256 | //get the object | 272 | //get the object |
| 257 | T *obj = dynamic_cast<T *>(node); | 273 | T *obj = std::is_same<T, ast_node>() ? static_cast<T*>(node) : ast_cast<T>(node); |
| 258 | 274 | ||
| 259 | //if the object is optional, simply return | 275 | //if the object is optional, simply return |
| 260 | if (OPT) { | 276 | if (OPT) { |
| @@ -337,7 +353,7 @@ public: | |||
| 337 | ast_node *obj = nullptr; | 353 | ast_node *obj = nullptr; |
| 338 | 354 | ||
| 339 | using swallow = bool[]; | 355 | using swallow = bool[]; |
| 340 | (void)swallow{obj || (obj = dynamic_cast<Args*>(node))...}; | 356 | (void)swallow{obj || (obj = std::is_same<Args, ast_node>() ? node : ast_cast<Args>(node))...}; |
| 341 | 357 | ||
| 342 | if (!obj) throw std::logic_error("invalid AST node"); | 358 | if (!obj) throw std::logic_error("invalid AST node"); |
| 343 | 359 | ||
| @@ -414,7 +430,7 @@ public: | |||
| 414 | ast_node *node = st.back(); | 430 | ast_node *node = st.back(); |
| 415 | 431 | ||
| 416 | //get the object | 432 | //get the object |
| 417 | T *obj = dynamic_cast<T *>(node); | 433 | T *obj = std::is_same<T, ast_node>() ? static_cast<T*>(node) : ast_cast<T>(node); |
| 418 | 434 | ||
| 419 | //if the object was not not of the appropriate type, | 435 | //if the object was not not of the appropriate type, |
| 420 | //end the list parsing | 436 | //end the list parsing |
| @@ -503,7 +519,7 @@ ast_node *parse(input &i, rule &g, error_list &el, void* ud); | |||
| 503 | */ | 519 | */ |
| 504 | template <class T> bool parse(input &i, rule &g, error_list &el, T *&ast, void* ud = nullptr) { | 520 | template <class T> bool parse(input &i, rule &g, error_list &el, T *&ast, void* ud = nullptr) { |
| 505 | ast_node *node = parse(i, g, el, ud); | 521 | ast_node *node = parse(i, g, el, ud); |
| 506 | ast = dynamic_cast<T *>(node); | 522 | ast = ast_cast<T>(node); |
| 507 | if (ast) return true; | 523 | if (ast) return true; |
| 508 | delete node; | 524 | delete node; |
| 509 | return false; | 525 | return false; |
diff --git a/MoonParser/main.cpp b/MoonParser/main.cpp index 985fdcf..202a8df 100644 --- a/MoonParser/main.cpp +++ b/MoonParser/main.cpp | |||
| @@ -50,7 +50,7 @@ struct Data | |||
| 50 | rule Any = any(); | 50 | rule Any = any(); |
| 51 | rule plain_space = *set(" \t"); | 51 | rule plain_space = *set(" \t"); |
| 52 | rule Break = nl(-expr('\r') >> '\n'); | 52 | rule Break = nl(-expr('\r') >> '\n'); |
| 53 | rule White = *(set(" \t\r") | Break); | 53 | rule White = *(set(" \t") | Break); |
| 54 | rule Stop = Break | eof(); | 54 | rule Stop = Break | eof(); |
| 55 | rule Comment = "--" >> *(not_(set("\r\n")) >> Any) >> and_(Stop); | 55 | rule Comment = "--" >> *(not_(set("\r\n")) >> Any) >> and_(Stop); |
| 56 | rule Indent = *set(" \t"); | 56 | rule Indent = *set(" \t"); |
| @@ -556,12 +556,14 @@ rule BlockEnd = Block >> eof(); | |||
| 556 | #define AST_LEAF(type) \ | 556 | #define AST_LEAF(type) \ |
| 557 | class type##_t : public ast_node \ | 557 | class type##_t : public ast_node \ |
| 558 | { \ | 558 | { \ |
| 559 | public: | 559 | public: \ |
| 560 | virtual int get_type() override { return ast_type<type##_t>(); } | ||
| 560 | 561 | ||
| 561 | #define AST_NODE(type) \ | 562 | #define AST_NODE(type) \ |
| 562 | class type##_t : public ast_container \ | 563 | class type##_t : public ast_container \ |
| 563 | { \ | 564 | { \ |
| 564 | public: | 565 | public: \ |
| 566 | virtual int get_type() override { return ast_type<type##_t>(); } | ||
| 565 | 567 | ||
| 566 | #define AST_END(type) \ | 568 | #define AST_END(type) \ |
| 567 | }; \ | 569 | }; \ |
| @@ -577,7 +579,6 @@ AST_LEAF(Num) | |||
| 577 | stream << static_cast<char>(*it); | 579 | stream << static_cast<char>(*it); |
| 578 | } | 580 | } |
| 579 | stream >> value; | 581 | stream >> value; |
| 580 | cout << value << '\n'; | ||
| 581 | } | 582 | } |
| 582 | AST_END(Num) | 583 | AST_END(Num) |
| 583 | 584 | ||
