aboutsummaryrefslogtreecommitdiff
path: root/MoonParser/ast.hpp
diff options
context:
space:
mode:
authorLi Jin <dragon-fly@qq.com>2017-07-16 17:05:31 +0800
committerLi Jin <dragon-fly@qq.com>2017-07-16 17:05:31 +0800
commit9e63302e5906d53d9f39f64c549b9aa7e806b669 (patch)
treea76f39ed3e6336e13fe58f2387495c8f091639a3 /MoonParser/ast.hpp
parentcb906e739f27931e9798510cd83725131ed55209 (diff)
downloadyuescript-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.hpp83
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) {}
57private: 61private:
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
288template <class ...Args> class ast_choice : public ast_member {
289public:
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
351private:
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.