diff options
Diffstat (limited to '')
| -rw-r--r-- | MoonParser/ast.hpp | 83 |
1 files changed, 81 insertions, 2 deletions
diff --git a/MoonParser/ast.hpp b/MoonParser/ast.hpp index 5d87db9..664c8af 100644 --- a/MoonParser/ast.hpp +++ b/MoonParser/ast.hpp | |||
| @@ -53,12 +53,17 @@ public: | |||
| 53 | @param st stack. | 53 | @param st stack. |
| 54 | */ | 54 | */ |
| 55 | virtual void construct(ast_stack &st) {} | 55 | virtual void construct(ast_stack &st) {} |
| 56 | 56 | ||
| 57 | /** interface for visiting AST tree use. | ||
| 58 | @param user_data vector for storing user data. | ||
| 59 | */ | ||
| 60 | virtual void visit(void* user_data) {} | ||
| 57 | private: | 61 | private: |
| 58 | //parent | 62 | //parent |
| 59 | ast_node *m_parent; | 63 | ast_node *m_parent; |
| 60 | 64 | ||
| 61 | template <class T, bool OPT> friend class ast_ptr; | 65 | template <class T, bool OPT> friend class ast_ptr; |
| 66 | template <class ...Args> friend class ast_choice; | ||
| 62 | template <class T> friend class ast_list; | 67 | template <class T> friend class ast_list; |
| 63 | template <class T> friend class ast; | 68 | template <class T> friend class ast; |
| 64 | }; | 69 | }; |
| @@ -240,7 +245,10 @@ public: | |||
| 240 | */ | 245 | */ |
| 241 | virtual void construct(ast_stack &st) { | 246 | virtual void construct(ast_stack &st) { |
| 242 | //check the stack node | 247 | //check the stack node |
| 243 | if (st.empty()) throw std::logic_error("invalid AST stack"); | 248 | if (st.empty()) { |
| 249 | if (OPT) return; | ||
| 250 | else throw std::logic_error("invalid AST stack"); | ||
| 251 | } | ||
| 244 | 252 | ||
| 245 | //get the node | 253 | //get the node |
| 246 | ast_node *node = st.back(); | 254 | ast_node *node = st.back(); |
| @@ -277,6 +285,77 @@ private: | |||
| 277 | } | 285 | } |
| 278 | }; | 286 | }; |
| 279 | 287 | ||
| 288 | template <class ...Args> class ast_choice : public ast_member { | ||
| 289 | public: | ||
| 290 | ast_choice(ast_node *obj = 0) : m_ptr(obj) { | ||
| 291 | _set_parent(); | ||
| 292 | } | ||
| 293 | |||
| 294 | ast_choice(const ast_choice<Args...> &src) : | ||
| 295 | m_ptr(src.m_ptr ? new ast_node(*src.m_ptr) : 0) | ||
| 296 | { | ||
| 297 | _set_parent(); | ||
| 298 | } | ||
| 299 | |||
| 300 | ~ast_choice() { | ||
| 301 | delete m_ptr; | ||
| 302 | } | ||
| 303 | |||
| 304 | ast_choice<Args...> &operator = (const ast_node *obj) { | ||
| 305 | delete m_ptr; | ||
| 306 | m_ptr = obj ? new ast_node(*obj) : 0; | ||
| 307 | _set_parent(); | ||
| 308 | return *this; | ||
| 309 | } | ||
| 310 | |||
| 311 | ast_choice<Args...> &operator = (const ast_choice<Args...> &src) { | ||
| 312 | delete m_ptr; | ||
| 313 | m_ptr = src.m_ptr ? new ast_node(*src.m_ptr) : 0; | ||
| 314 | _set_parent(); | ||
| 315 | return *this; | ||
| 316 | } | ||
| 317 | |||
| 318 | ast_node *get() const { | ||
| 319 | return m_ptr; | ||
| 320 | } | ||
| 321 | |||
| 322 | operator ast_node *() const { | ||
| 323 | return m_ptr; | ||
| 324 | } | ||
| 325 | |||
| 326 | ast_node *operator ->() const { | ||
| 327 | assert(m_ptr); | ||
| 328 | return m_ptr; | ||
| 329 | } | ||
| 330 | |||
| 331 | virtual void construct(ast_stack &st) { | ||
| 332 | if (st.empty()) { | ||
| 333 | throw std::logic_error("invalid AST stack"); | ||
| 334 | } | ||
| 335 | |||
| 336 | ast_node *node = st.back(); | ||
| 337 | ast_node *obj = nullptr; | ||
| 338 | |||
| 339 | using swallow = bool[]; | ||
| 340 | (void)swallow{obj || (obj = dynamic_cast<Args*>(node))...}; | ||
| 341 | |||
| 342 | if (!obj) throw std::logic_error("invalid AST node"); | ||
| 343 | |||
| 344 | st.pop_back(); | ||
| 345 | |||
| 346 | delete m_ptr; | ||
| 347 | m_ptr = obj; | ||
| 348 | _set_parent(); | ||
| 349 | } | ||
| 350 | |||
| 351 | private: | ||
| 352 | //ptr | ||
| 353 | ast_node *m_ptr; | ||
| 354 | |||
| 355 | void _set_parent() { | ||
| 356 | if (m_ptr) m_ptr->m_parent = container(); | ||
| 357 | } | ||
| 358 | }; | ||
| 280 | 359 | ||
| 281 | /** A list of objects. | 360 | /** A list of objects. |
| 282 | It pops objects of the given type from the ast stack, until no more objects can be popped. | 361 | It pops objects of the given type from the ast stack, until no more objects can be popped. |
