text: // sequence_node.hpp
  // Copyright (c) 2007 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_SEQUENCE_NODE_HPP
  #define BOOST_LEXER_SEQUENCE_NODE_HPP
  
  #include "node.hpp"
  
  namespace boost
  {
  namespace lexer
  {
  namespace detail
  {
  class sequence_node : public node
  {
  public:
      sequence_node (node *left_, node *right_) :
          node (left_->nullable () && right_->nullable ()),
          _left (left_),
          _right (right_)
      {
          _left->append_firstpos (_firstpos);
  
          if (_left->nullable ())
          {
              _right->append_firstpos (_firstpos);
          }
  
          if (_right->nullable ())
          {
              _left->append_lastpos (_lastpos);
          }
  
          _right->append_lastpos (_lastpos);
  
          node_vector &lastpos_ = _left->lastpos ();
          const node_vector &firstpos_ = _right->firstpos ();
  
          for (node_vector::iterator iter_ = lastpos_.begin (),
              end_ = lastpos_.end (); iter_ != end_; ++iter_)
          {
              (*iter_)->append_followpos (firstpos_);
          }
      }
  
      virtual ~sequence_node ()
      {
      }
  
      virtual type what_type () const
      {
          return SEQUENCE;
      }
  
      virtual bool traverse (const_node_stack &node_stack_,
          bool_stack &perform_op_stack_) const
      {
          perform_op_stack_.push (true);
  
          switch (_right->what_type ())
          {
          case SEQUENCE:
          case SELECTION:
          case ITERATION:
              perform_op_stack_.push (false);
              break;
          default:
              break;
          }
  
          node_stack_.push (_right);
          node_stack_.push (_left);
          return true;
      }
  
  private:
      // Not owner of these pointers...
      node *_left;
      node *_right;
  
      virtual void copy_node (node_ptr_vector &node_ptr_vector_,
          node_stack &new_node_stack_, bool_stack &perform_op_stack_,
          bool &down_) const
      {
          if (perform_op_stack_.top ())
          {
              node *rhs_ = new_node_stack_.top ();
  
              new_node_stack_.pop ();
  
              node *lhs_ = new_node_stack_.top ();
  
              node_ptr_vector_->push_back (0);
              node_ptr_vector_->back () = new sequence_node (lhs_, rhs_);
              new_node_stack_.top () = node_ptr_vector_->back ();
          }
          else
          {
              down_ = true;
          }
  
          perform_op_stack_.pop ();
      }
  };
  }
  }
  }
  
  #endif
  