| | #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; |
| | } |
| |
|
| | } |
| | } |
| | } |
| |
|