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 }