From 21328c2299eebc03c13478d7d214f9ed58d9688e Mon Sep 17 00:00:00 2001 From: Li Jin Date: Sun, 16 Jul 2017 23:47:58 +0800 Subject: remove uses of dynamic_cast. --- MoonParser/ast.cpp | 2 ++ MoonParser/ast.hpp | 24 ++++++++++++++++++++---- 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 { //current AST container. static ast_container *_current = 0; +int ast_type_id = 0; + /** sets the container under construction to be this. */ 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 @@ #include #include #include +#include #include "parser.hpp" @@ -21,6 +22,14 @@ template class ast; */ typedef std::vector ast_stack; +extern int ast_type_id; + +template +int ast_type() +{ + static int type = ast_type_id++; + return type; +} /** Base class for AST nodes. */ @@ -58,6 +67,8 @@ public: @param user_data vector for storing user data. */ virtual void visit(void* user_data) {} + + virtual int get_type() { return ast_type(); } private: //parent ast_node *m_parent; @@ -68,6 +79,11 @@ private: template friend class ast; }; +template +T* ast_cast(ast_node *node) +{ + return ast_type() == node->get_type() ? static_cast(node) : nullptr; +} class ast_member; @@ -254,7 +270,7 @@ public: ast_node *node = st.back(); //get the object - T *obj = dynamic_cast(node); + T *obj = std::is_same() ? static_cast(node) : ast_cast(node); //if the object is optional, simply return if (OPT) { @@ -337,7 +353,7 @@ public: ast_node *obj = nullptr; using swallow = bool[]; - (void)swallow{obj || (obj = dynamic_cast(node))...}; + (void)swallow{obj || (obj = std::is_same() ? node : ast_cast(node))...}; if (!obj) throw std::logic_error("invalid AST node"); @@ -414,7 +430,7 @@ public: ast_node *node = st.back(); //get the object - T *obj = dynamic_cast(node); + T *obj = std::is_same() ? static_cast(node) : ast_cast(node); //if the object was not not of the appropriate type, //end the list parsing @@ -503,7 +519,7 @@ ast_node *parse(input &i, rule &g, error_list &el, void* ud); */ template bool parse(input &i, rule &g, error_list &el, T *&ast, void* ud = nullptr) { ast_node *node = parse(i, g, el, ud); - ast = dynamic_cast(node); + ast = ast_cast(node); if (ast) return true; delete node; 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 rule Any = any(); rule plain_space = *set(" \t"); rule Break = nl(-expr('\r') >> '\n'); -rule White = *(set(" \t\r") | Break); +rule White = *(set(" \t") | Break); rule Stop = Break | eof(); rule Comment = "--" >> *(not_(set("\r\n")) >> Any) >> and_(Stop); rule Indent = *set(" \t"); @@ -556,12 +556,14 @@ rule BlockEnd = Block >> eof(); #define AST_LEAF(type) \ class type##_t : public ast_node \ { \ -public: +public: \ + virtual int get_type() override { return ast_type(); } #define AST_NODE(type) \ class type##_t : public ast_container \ { \ -public: +public: \ + virtual int get_type() override { return ast_type(); } #define AST_END(type) \ }; \ @@ -577,7 +579,6 @@ AST_LEAF(Num) stream << static_cast(*it); } stream >> value; - cout << value << '\n'; } AST_END(Num) -- cgit v1.2.3-55-g6feb