|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include "VarSpanTrieBuilder.h" |
|
|
|
|
|
#include "ApplicableRuleTrie.h" |
|
|
#include "IntermediateVarSpanNode.h" |
|
|
#include "VarSpanNode.h" |
|
|
|
|
|
#include <algorithm> |
|
|
#include <vector> |
|
|
|
|
|
namespace Moses |
|
|
{ |
|
|
|
|
|
std::auto_ptr<VarSpanNode> VarSpanTrieBuilder::Build( |
|
|
ApplicableRuleTrie &root) |
|
|
{ |
|
|
std::auto_ptr<VarSpanNode> vstRoot(new VarSpanNode()); |
|
|
NodeVec vec; |
|
|
const std::vector<ApplicableRuleTrie*> &children = root.m_children; |
|
|
for (std::vector<ApplicableRuleTrie*>::const_iterator p = children.begin(); |
|
|
p != children.end(); ++p) { |
|
|
Build(**p, vec, *(vstRoot.get())); |
|
|
} |
|
|
return vstRoot; |
|
|
} |
|
|
|
|
|
void VarSpanTrieBuilder::Build(ApplicableRuleTrie &artNode, |
|
|
NodeVec &vec, |
|
|
VarSpanNode &vstRoot) |
|
|
{ |
|
|
typedef IntermediateVarSpanNode::Range Range; |
|
|
|
|
|
|
|
|
|
|
|
NodeVecState state; |
|
|
RecordState(vec, state); |
|
|
|
|
|
if (artNode.m_end == -1) { |
|
|
if (!vec.empty() && vec.back().isOpen()) { |
|
|
++(vec.back().m_numSplitPoints); |
|
|
++(vec.back().m_end.first); |
|
|
} else if (artNode.m_start == -1) { |
|
|
Range start(0, -1); |
|
|
Range end(0, -1); |
|
|
vec.push_back(IntermediateVarSpanNode(start, end)); |
|
|
} else { |
|
|
Range start(artNode.m_start, artNode.m_start); |
|
|
Range end(artNode.m_start, -1); |
|
|
vec.push_back(IntermediateVarSpanNode(start, end)); |
|
|
} |
|
|
} else if (!vec.empty() && vec.back().isOpen()) { |
|
|
vec.back().m_end = Range(artNode.m_start-1, artNode.m_start-1); |
|
|
if (vec.back().m_start.second == -1) { |
|
|
size_t s = artNode.m_start - (vec.back().m_numSplitPoints + 1); |
|
|
vec.back().m_start.second = s; |
|
|
} |
|
|
} |
|
|
|
|
|
if (artNode.m_node->HasRules()) { |
|
|
artNode.m_vstNode = &(vstRoot.Insert(vec)); |
|
|
} |
|
|
|
|
|
const std::vector<ApplicableRuleTrie*> &children = artNode.m_children; |
|
|
for (std::vector<ApplicableRuleTrie*>::const_iterator p = children.begin(); |
|
|
p != children.end(); ++p) { |
|
|
Build(**p, vec, vstRoot); |
|
|
} |
|
|
|
|
|
|
|
|
RestoreState(state, vec); |
|
|
} |
|
|
|
|
|
void VarSpanTrieBuilder::RecordState(const NodeVec &vec, NodeVecState &state) |
|
|
{ |
|
|
state.m_size = vec.size(); |
|
|
if (!vec.empty()) { |
|
|
state.m_lastNode = vec.back(); |
|
|
} |
|
|
} |
|
|
|
|
|
void VarSpanTrieBuilder::RestoreState(const NodeVecState &state, NodeVec &vec) |
|
|
{ |
|
|
assert(state.m_size == vec.size() || state.m_size+1 == vec.size()); |
|
|
if (state.m_size < vec.size()) { |
|
|
vec.resize(state.m_size); |
|
|
} else if (!vec.empty()) { |
|
|
vec.back() = state.m_lastNode; |
|
|
} |
|
|
} |
|
|
|
|
|
} |
|
|
|