| #pragma once |
|
|
| namespace Moses |
| { |
| namespace Syntax |
| { |
| namespace T2S |
| { |
|
|
| template<typename Callback> |
| RuleMatcherSCFG<Callback>::RuleMatcherSCFG(const InputTree &inputTree, |
| const RuleTrie &ruleTrie) |
| : m_inputTree(inputTree) |
| , m_ruleTrie(ruleTrie) |
| { |
| } |
|
|
| template<typename Callback> |
| void RuleMatcherSCFG<Callback>::EnumerateHyperedges(const InputTree::Node &node, |
| Callback &callback) |
| { |
| const int start = static_cast<int>(node.pvertex.span.GetStartPos()); |
| m_hyperedge.head = const_cast<PVertex*>(&node.pvertex); |
| m_hyperedge.tail.clear(); |
| Match(node, m_ruleTrie.GetRootNode(), start, callback); |
| } |
|
|
| template<typename Callback> |
| void RuleMatcherSCFG<Callback>::Match(const InputTree::Node &inNode, |
| const RuleTrie::Node &trieNode, |
| int start, Callback &callback) |
| { |
| |
| |
| const std::vector<InputTree::Node*> &nodes = m_inputTree.nodesAtPos[start]; |
| for (std::vector<InputTree::Node*>::const_iterator p = nodes.begin(); |
| p != nodes.end(); ++p) { |
| InputTree::Node &candidate = **p; |
| |
| if (!IsDescendent(candidate, inNode)) { |
| continue; |
| } |
| |
| |
| const RuleTrie::Node::SymbolMap *map = NULL; |
| if (candidate.children.empty()) { |
| map = &(trieNode.GetTerminalMap()); |
| } else { |
| map = &(trieNode.GetNonTerminalMap()); |
| } |
| |
| RuleTrie::Node::SymbolMap::const_iterator q = |
| map->find(candidate.pvertex.symbol); |
| if (q == map->end()) { |
| continue; |
| } |
| const RuleTrie::Node &newTrieNode = q->second; |
| |
| m_hyperedge.tail.push_back(&candidate.pvertex); |
| |
| if (candidate.pvertex.span.GetEndPos() == inNode.pvertex.span.GetEndPos()) { |
| |
| const Word &lhs = inNode.pvertex.symbol; |
| TargetPhraseCollection::shared_ptr tpc = |
| newTrieNode.GetTargetPhraseCollection(lhs); |
| if (tpc) { |
| m_hyperedge.label.translations = tpc; |
| callback(m_hyperedge); |
| } |
| } else { |
| |
| int newStart = candidate.pvertex.span.GetEndPos()+1; |
| Match(inNode, newTrieNode, newStart, callback); |
| } |
| m_hyperedge.tail.pop_back(); |
| } |
| } |
|
|
| |
| template<typename Callback> |
| bool RuleMatcherSCFG<Callback>::IsDescendent(const InputTree::Node &x, |
| const InputTree::Node &y) |
| { |
| const std::size_t xStart = x.pvertex.span.GetStartPos(); |
| const std::size_t yStart = y.pvertex.span.GetStartPos(); |
| const std::size_t xEnd = x.pvertex.span.GetEndPos(); |
| const std::size_t yEnd = y.pvertex.span.GetEndPos(); |
| if (xStart < yStart || xEnd > yEnd) { |
| return false; |
| } |
| if (xStart > yStart || xEnd < yEnd) { |
| return true; |
| } |
| |
| const InputTree::Node *z = &y; |
| while (z->children.size() == 1) { |
| z = z->children[0]; |
| if (z == &x) { |
| return true; |
| } |
| } |
| return false; |
| } |
|
|
| } |
| } |
| } |
|
|