diff options
author | Li Jin <dragon-fly@qq.com> | 2017-07-16 17:05:31 +0800 |
---|---|---|
committer | Li Jin <dragon-fly@qq.com> | 2017-07-16 17:05:31 +0800 |
commit | 9e63302e5906d53d9f39f64c549b9aa7e806b669 (patch) | |
tree | a76f39ed3e6336e13fe58f2387495c8f091639a3 /MoonParser/ast.hpp | |
parent | cb906e739f27931e9798510cd83725131ed55209 (diff) | |
download | yuescript-parserlib.tar.gz yuescript-parserlib.tar.bz2 yuescript-parserlib.zip |
AST generating succeeded.parserlib
Diffstat (limited to 'MoonParser/ast.hpp')
-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. |