| // 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 <assert.h> |
| #include "../../containers/ptr_vector.hpp" |
| #include "../../runtime_error.hpp" |
| #include "../../size_t.hpp" |
| #include <stack> |
| #include <vector> |
| |
| namespace boost |
| { |
| namespace lexer |
| { |
| namespace detail |
| { |
| class node |
| { |
| public: |
| enum type {LEAF, SEQUENCE, SELECTION, ITERATION, END}; |
| |
| typedef std::stack<bool> bool_stack; |
| typedef std::stack<node *> node_stack; |
| // stack and vector not owner of node pointers |
| typedef std::stack<const node *> const_node_stack; |
| typedef std::vector<node *> node_vector; |
| typedef ptr_vector<node> 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 (); |
| } |
| } |
| |
| 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 |