00001 #include "InternalTree.h" 00002 00003 namespace MosesTuning 00004 { 00005 00006 InternalTree::InternalTree(const std::string & line, const bool terminal): 00007 m_isTerminal(terminal) 00008 { 00009 00010 size_t found = line.find_first_of("[] "); 00011 00012 if (found == line.npos) { 00013 m_value = line; 00014 } 00015 00016 else { 00017 AddSubTree(line, 0); 00018 } 00019 } 00020 00021 size_t InternalTree::AddSubTree(const std::string & line, size_t pos) 00022 { 00023 00024 std::string value; 00025 char token = 0; 00026 00027 while (token != ']' && pos != std::string::npos) { 00028 size_t oldpos = pos; 00029 pos = line.find_first_of("[] ", pos); 00030 if (pos == std::string::npos) break; 00031 token = line[pos]; 00032 value = line.substr(oldpos,pos-oldpos); 00033 00034 if (token == '[') { 00035 if (m_value.size() > 0) { 00036 m_children.push_back(boost::make_shared<InternalTree>(value,false)); 00037 pos = m_children.back()->AddSubTree(line, pos+1); 00038 } else { 00039 if (value.size() > 0) { 00040 m_value = value; 00041 } 00042 pos = AddSubTree(line, pos+1); 00043 } 00044 } else if (token == ' ' || token == ']') { 00045 if (value.size() > 0 && !(m_value.size() > 0)) { 00046 m_value = value; 00047 } else if (value.size() > 0) { 00048 m_isTerminal = false; 00049 m_children.push_back(boost::make_shared<InternalTree>(value,true)); 00050 } 00051 if (token == ' ') { 00052 pos++; 00053 } 00054 } 00055 00056 if (m_children.size() > 0) { 00057 m_isTerminal = false; 00058 } 00059 } 00060 00061 if (pos == std::string::npos) { 00062 return line.size(); 00063 } 00064 return std::min(line.size(),pos+1); 00065 00066 } 00067 00068 std::string InternalTree::GetString(bool start) const 00069 { 00070 00071 std::string ret = ""; 00072 if (!start) { 00073 ret += " "; 00074 } 00075 00076 if (!m_isTerminal) { 00077 ret += "["; 00078 } 00079 00080 ret += m_value; 00081 for (std::vector<TreePointer>::const_iterator it = m_children.begin(); it != m_children.end(); ++it) { 00082 ret += (*it)->GetString(false); 00083 } 00084 00085 if (!m_isTerminal) { 00086 ret += "]"; 00087 } 00088 return ret; 00089 00090 } 00091 00092 00093 void InternalTree::Combine(const std::vector<TreePointer> &previous) 00094 { 00095 00096 std::vector<TreePointer>::iterator it; 00097 bool found = false; 00098 leafNT next_leafNT(this); 00099 for (std::vector<TreePointer>::const_iterator it_prev = previous.begin(); it_prev != previous.end(); ++it_prev) { 00100 found = next_leafNT(it); 00101 if (found) { 00102 *it = *it_prev; 00103 } else { 00104 std::cerr << "Warning: leaf nonterminal not found in rule; why did this happen?\n"; 00105 } 00106 } 00107 } 00108 00109 00110 }