// node.hpp // Copyright (c) 2005-2012 Ben Hanson (http://www.benhanson.net/) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #ifndef LEXERTL_NODE_HPP #define LEXERTL_NODE_HPP #include #include "../../containers/ptr_vector.hpp" #include "../../runtime_error.hpp" #include "../../size_t.hpp" #include #include namespace lexertl { namespace detail { template class basic_node { public: enum node_type {LEAF, SEQUENCE, SELECTION, ITERATION, END}; typedef std::stack bool_stack; typedef std::stack *> node_stack; // stack and vector not owner of node pointers typedef std::stack *> const_node_stack; typedef std::vector *> node_vector; typedef ptr_vector > node_ptr_vector; basic_node () : _nullable (false), _firstpos (), _lastpos () { } basic_node (const bool nullable_) : _nullable (nullable_), _firstpos (), _lastpos () { } virtual ~basic_node () { } static id_type null_token () { return static_cast(~0); } bool nullable () const { return _nullable; } void append_firstpos (node_vector &firstpos_) const { firstpos_.insert (firstpos_.end (), _firstpos.begin (), _firstpos.end ()); } void append_lastpos (node_vector &lastpos_) const { lastpos_.insert (lastpos_.end (), _lastpos.begin (), _lastpos.end ()); } virtual void append_followpos (const node_vector &/*followpos_*/) { throw runtime_error ("Internal error node::append_followpos()."); } basic_node *copy (node_ptr_vector &node_ptr_vector_) const { basic_node *new_root_ = 0; const_node_stack node_stack_; bool_stack perform_op_stack_; bool down_ = true; node_stack new_node_stack_; node_stack_.push (this); while (!node_stack_.empty ()) { while (down_) { down_ = node_stack_.top ()->traverse (node_stack_, perform_op_stack_); } while (!down_ && !node_stack_.empty ()) { const basic_node *top_ = node_stack_.top (); top_->copy_node (node_ptr_vector_, new_node_stack_, perform_op_stack_, down_); if (!down_) node_stack_.pop (); } } assert (new_node_stack_.size () == 1); new_root_ = new_node_stack_.top (); new_node_stack_.pop (); return new_root_; } virtual node_type what_type () const = 0; virtual bool traverse (const_node_stack &node_stack_, bool_stack &perform_op_stack_) const = 0; node_vector &firstpos () { return _firstpos; } const node_vector &firstpos () const { return _firstpos; } // _lastpos modified externally, so not const & node_vector &lastpos () { return _lastpos; } virtual bool end_state () const { return false; } virtual id_type id () const { throw runtime_error ("Internal error node::id()."); #ifdef __SUNPRO_CC // Stop bogus Solaris compiler warning return id_type (); #endif } virtual id_type user_id () const { throw runtime_error ("Internal error node::user_id()."); #ifdef __SUNPRO_CC // Stop bogus Solaris compiler warning return id_type (); #endif } virtual id_type next_dfa () const { throw runtime_error ("Internal error node::next_dfa()."); #ifdef __SUNPRO_CC // Stop bogus Solaris compiler warning return id_type (); #endif } virtual id_type push_dfa () const { throw runtime_error ("Internal error node::push_dfa()."); #ifdef __SUNPRO_CC // Stop bogus Solaris compiler warning return id_type (); #endif } virtual bool pop_dfa () const { throw runtime_error ("Internal error node::pop_dfa()."); #ifdef __SUNPRO_CC // Stop bogus Solaris compiler warning return false; #endif } virtual id_type token () const { throw runtime_error ("Internal error node::token()."); #ifdef __SUNPRO_CC // Stop bogus Solaris compiler warning return id_type (); #endif } virtual void greedy (const bool /*greedy_*/) { throw runtime_error ("Internal error node::greedy(bool)."); } virtual bool greedy () const { throw runtime_error ("Internal error node::greedy()."); #ifdef __SUNPRO_CC // Stop bogus Solaris compiler warning return false; #endif } virtual const node_vector &followpos () const { throw runtime_error ("Internal error node::followpos()."); #ifdef __SUNPRO_CC // Stop bogus Solaris compiler warning return firstpos; #endif } virtual node_vector &followpos () { throw runtime_error ("Internal error node::followpos()."); #ifdef __SUNPRO_CC // Stop bogus Solaris compiler warning return firstpos; #endif } protected: const bool _nullable; node_vector _firstpos; node_vector _lastpos; virtual void copy_node (node_ptr_vector &node_ptr_vector_, node_stack &new_node_stack_, bool_stack &perform_op_stack_, bool &down_) const = 0; private: basic_node (const basic_node &); // No copy construction. const basic_node &operator = (const basic_node &); // No assignment. }; } } #endif