#pragma once #include #include namespace MosesTraining { namespace Syntax { template Tree::~Tree() { for (typename std::vector::iterator p = children_.begin(); p != children_.end(); ++p) { delete *p; } } template void Tree::SetParents() { for (typename std::vector::iterator p = children_.begin(); p != children_.end(); ++p) { (*p)->parent() = this; (*p)->SetParents(); } } template std::size_t Tree::Depth() const { std::size_t depth = 0; Tree *ancestor = parent_; while (ancestor != 0) { ++depth; ancestor = ancestor->parent_; } return depth; } template class Tree::PreOrderIterator { public: PreOrderIterator(); PreOrderIterator(Tree &); Tree &operator*() { return *node_; } Tree *operator->() { return node_; } PreOrderIterator &operator++(); PreOrderIterator operator++(int); bool operator==(const Tree::PreOrderIterator &); bool operator!=(const Tree::PreOrderIterator &); private: // Pointer to the current node. Tree *node_; // Stack of indices defining the position of node_ within the child vectors // of its ancestors. std::stack index_stack_; }; template Tree::PreOrderIterator::PreOrderIterator() : node_(0) { } template Tree::PreOrderIterator::PreOrderIterator(Tree &t) : node_(&t) { } template typename Tree::PreOrderIterator &Tree::PreOrderIterator::operator++() { // If the current node has children then visit the left-most child next. if (!node_->children().empty()) { index_stack_.push(0); node_ = node_->children()[0]; return *this; } // Otherwise, try node's ancestors until either a node is found with a // sibling to the right or we reach the root (in which case the traversal // is complete). Tree *ancestor = node_->parent_; while (ancestor) { std::size_t index = index_stack_.top(); index_stack_.pop(); if (index+1 < ancestor->children_.size()) { index_stack_.push(index+1); node_ = ancestor->children()[index+1]; return *this; } ancestor = ancestor->parent_; } node_ = 0; return *this; } template typename Tree::PreOrderIterator Tree::PreOrderIterator::operator++(int) { PreOrderIterator tmp(*this); ++*this; return tmp; } template bool Tree::PreOrderIterator::operator==(const PreOrderIterator &rhs) { return node_ == rhs.node_; } template bool Tree::PreOrderIterator::operator!=(const PreOrderIterator &rhs) { return node_ != rhs.node_; } } // namespace Syntax } // namespace MosesTraining