Commit 19cd8c2f authored by Davis King's avatar Davis King

Added parse_trees_to_string() and parse_trees_to_string_tagged(). Also made

the output slightly nicer looking.
parent 0ae9ee47
......@@ -232,26 +232,30 @@ namespace dlib
std::ostream&
) { }
template <bool print_tag, typename T, typename U >
template <bool print_tag, bool skip_tag, typename T, typename U >
void print_parse_tree_helper (
const std::vector<parse_tree_element<T> >& tree,
const std::vector<U>& words,
unsigned long i,
const T& tag_to_skip,
std::ostream& out
)
{
out << "[";
if (!skip_tag || tree[i].tag != tag_to_skip)
out << "[";
bool left_recurse = false;
// Only print if we are supposed to. Doing it this funny way avoids compiler
// errors in parse_tree_to_string() for the case where tag isn't
// printable.
conditional_print<print_tag>(tree[i].tag, out);
if (!skip_tag || tree[i].tag != tag_to_skip)
conditional_print<print_tag>(tree[i].tag, out);
if (tree[i].left < tree.size())
{
left_recurse = true;
print_parse_tree_helper<print_tag>(tree, words, tree[i].left, out);
print_parse_tree_helper<print_tag,skip_tag>(tree, words, tree[i].left, tag_to_skip, out);
}
else
{
......@@ -268,12 +272,12 @@ namespace dlib
}
}
if (left_recurse == true)
out << " ";
if (tree[i].right < tree.size())
{
if (left_recurse == true)
out << " ";
print_parse_tree_helper<print_tag>(tree, words, tree[i].right, out);
print_parse_tree_helper<print_tag,skip_tag>(tree, words, tree[i].right, tag_to_skip, out);
}
else
{
......@@ -291,7 +295,8 @@ namespace dlib
}
out << "]";
if (!skip_tag || tree[i].tag != tag_to_skip)
out << "]";
}
}
......@@ -308,7 +313,7 @@ namespace dlib
return "";
std::ostringstream sout;
impl::print_parse_tree_helper<false>(tree, words, root_idx, sout);
impl::print_parse_tree_helper<false,false>(tree, words, root_idx, tree[root_idx].tag, sout);
return sout.str();
}
......@@ -325,7 +330,41 @@ namespace dlib
return "";
std::ostringstream sout;
impl::print_parse_tree_helper<true>(tree, words, root_idx, sout);
impl::print_parse_tree_helper<true,false>(tree, words, root_idx, tree[root_idx].tag, sout);
return sout.str();
}
// -----------------------------------------------------------------------------------------
template <typename T, typename U>
std::string parse_trees_to_string (
const std::vector<parse_tree_element<T> >& tree,
const std::vector<U>& words,
const unsigned long root_idx = 0
)
{
if (root_idx >= tree.size())
return "";
std::ostringstream sout;
impl::print_parse_tree_helper<false,true>(tree, words, root_idx, tree[root_idx].tag, sout);
return sout.str();
}
// -----------------------------------------------------------------------------------------
template <typename T, typename U>
std::string parse_trees_to_string_tagged (
const std::vector<parse_tree_element<T> >& tree,
const std::vector<U>& words,
const unsigned long root_idx = 0
)
{
if (root_idx >= tree.size())
return "";
std::ostringstream sout;
impl::print_parse_tree_helper<true,true>(tree, words, root_idx, tree[root_idx].tag, sout);
return sout.str();
}
......
......@@ -289,6 +289,63 @@ namespace dlib
shorted than it is supposed to be.
!*/
// -----------------------------------------------------------------------------------------
template <
typename T,
typename U
>
std::string parse_trees_to_string (
const std::vector<parse_tree_element<T> >& tree,
const std::vector<U>& words,
const unsigned long root_idx = 0
);
/*!
requires
- It must be possible to print U objects to an ostream using operator<<
(typically, U would be something like std::string)
ensures
- This function behaves just like parse_tree_to_string() except that it will
not print the brackets (i.e. []) for the top most parts of the tree which
have tags equal to tree[root_idx].tag. It will however print all the words.
Therefore, this function only includes brackets on the subtrees which begin
with a tag other than tree[root_idx].tag.
throws
- parse_tree_to_string_error
This exception is thrown if an invalid tree is detected. This might happen
if the tree refers to elements of words that don't exist because words is
shorted than it is supposed to be.
!*/
// -----------------------------------------------------------------------------------------
template <
typename T,
typename U
>
std::string parse_trees_to_string_tagged (
const std::vector<parse_tree_element<T> >& tree,
const std::vector<U>& words,
const unsigned long root_idx = 0
);
/*!
requires
- It must be possible to print T objects to an ostream using operator<<
- It must be possible to print U objects to an ostream using operator<<
(typically, U would be something like std::string)
ensures
- This function behaves just like parse_tree_to_string_tagged() except that it
will not print the brackets (i.e. []) for the top most parts of the tree
which have tags equal to tree[root_idx].tag. It will however print all the
words. Therefore, this function only includes brackets on the subtrees which
begin with a tag other than tree[root_idx].tag.
throws
- parse_tree_to_string_error
This exception is thrown if an invalid tree is detected. This might happen
if the tree refers to elements of words that don't exist because words is
shorted than it is supposed to be.
!*/
// -----------------------------------------------------------------------------------------
template <
......
......@@ -28,6 +28,7 @@ namespace
const unsigned long S = 5;
const unsigned long B = 6;
const unsigned long G = 7;
const unsigned long A = 8;
typedef unsigned long tags;
......@@ -43,6 +44,7 @@ namespace
if (c.left_tag == NP && c.right_tag == VP) possible_ids.push_back(make_pair(S,log(0.80)));
else if (c.left_tag == DET && c.right_tag == N) possible_ids.push_back(make_pair(NP,log(0.30)));
else if (c.left_tag == VP && c.right_tag == A) possible_ids.push_back(make_pair(VP,log(0.30)));
else if (c.left_tag == V && c.right_tag == NP)
{
possible_ids.push_back(make_pair(VP,log(0.20)));
......@@ -70,12 +72,14 @@ namespace
sequence.push_back(V);
sequence.push_back(DET);
sequence.push_back(N);
sequence.push_back(A);
words.push_back("The");
words.push_back("flight");
words.push_back("includes");
words.push_back("a");
words.push_back("meal");
words.push_back("AWORD");
}
std::vector<parse_tree_element<tags> > parse_tree;
......@@ -91,9 +95,9 @@ namespace
for (unsigned long i = 0; i < roots.size(); ++i)
{
dlog << LINFO << parse_tree_to_string(parse_tree, words, roots[i]);
DLIB_TEST(parse_tree_to_string(parse_tree, words, roots[i]) == "[[The flight] [includes [a meal]]]");
DLIB_TEST(parse_tree_to_string(parse_tree, words, roots[i]) == "[[The flight] [[includes [a meal]] AWORD]]");
dlog << LINFO << parse_tree_to_string_tagged(parse_tree, words, roots[i]);
DLIB_TEST(parse_tree_to_string_tagged(parse_tree, words, roots[i]) == "[5 [3 The flight] [4 includes [3 a meal]]]");
DLIB_TEST(parse_tree_to_string_tagged(parse_tree, words, roots[i]) == "[5 [3 The flight] [4 [4 includes [3 a meal]] AWORD]]");
}
......@@ -125,6 +129,13 @@ namespace
dlog << LINFO << parse_tree_to_string_tagged(parse_tree, words);
DLIB_TEST(parse_tree_to_string_tagged(parse_tree, words) == str2);
const std::string str3 = "[[The flight] [includes [a meal]]] [[The flight] [includes [a meal]]]";
const std::string str4 = "[5 [3 The flight] [4 includes [3 a meal]]] [5 [3 The flight] [4 includes [3 a meal]]]";
dlog << LINFO << parse_trees_to_string(parse_tree, words);
DLIB_TEST(parse_trees_to_string(parse_tree, words) == str3);
dlog << LINFO << parse_trees_to_string_tagged(parse_tree, words);
DLIB_TEST(parse_trees_to_string_tagged(parse_tree, words) == str4);
sequence.clear();
find_max_parse_cky(sequence, user_defined_ruleset<true>, parse_tree);
DLIB_TEST(parse_tree.size() == 0);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment