// node.hpp // Copyright (c) 2007-2009 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 BOOST_LEXER_NODE_HPP #define BOOST_LEXER_NODE_HPP #include #include "../../containers/ptr_vector.hpp" #include "../../runtime_error.hpp" #include "../../size_t.hpp" #include #include namespace boost { namespace lexer { namespace detail { class node { public: enum 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; node () : _nullable (false) { } node (const bool nullable_) : _nullable (nullable_) { } virtual ~node () { } 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()"); } node *copy (node_ptr_vector &node_ptr_vector_) const { 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 node *top_ = node_stack_.top (); top_->copy_node (node_ptr_vector_, new_node_stack_, perform_op_stack_, down_); if (!down_) node_stack_.pop (); } } BOOST_ASSERT(new_node_stack_.size () == 1); new_root_ = new_node_stack_.top (); new_node_stack_.pop (); return new_root_; } virtual 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 std::size_t id () const { throw runtime_error ("Internal error node::id()"); } virtual std::size_t unique_id () const { throw runtime_error ("Internal error node::unique_id()"); } virtual std::size_t lexer_state () const { throw runtime_error ("Internal error node::state()"); } virtual std::size_t token () const { throw runtime_error ("Internal error node::token()"); } virtual void greedy (const bool /*greedy_*/) { throw runtime_error ("Internal error node::token(bool)"); } virtual bool greedy () const { throw runtime_error ("Internal error node::token()"); } virtual const node_vector &followpos () const { throw runtime_error ("Internal error node::followpos()"); } virtual node_vector &followpos () { throw runtime_error ("Internal error node::followpos()"); } 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: node (node const &); // No copy construction. node &operator = (node const &); // No assignment. }; } } } #endif