2010-04-12 04:16:36 +04:00
|
|
|
#include "Tree.h"
|
|
|
|
#include "nodedumper.h"
|
|
|
|
|
|
|
|
#include <assert.h>
|
2011-09-11 09:33:18 +04:00
|
|
|
#include <algorithm>
|
|
|
|
|
2011-12-06 04:16:54 +04:00
|
|
|
Tree::~Tree()
|
|
|
|
{
|
|
|
|
this->nodecache.clear();
|
|
|
|
this->nodeidcache.clear();
|
|
|
|
}
|
|
|
|
|
2010-11-06 18:04:03 +03:00
|
|
|
/*!
|
2011-09-11 09:33:18 +04:00
|
|
|
Returns the cached string representation of the subtree rooted by \a node.
|
2010-11-06 18:04:03 +03:00
|
|
|
If node is not cached, the cache will be rebuilt.
|
|
|
|
*/
|
2011-09-11 11:10:31 +04:00
|
|
|
const std::string &Tree::getString(const AbstractNode &node) const
|
2010-04-12 04:16:36 +04:00
|
|
|
{
|
|
|
|
assert(this->root_node);
|
|
|
|
if (!this->nodecache.contains(node)) {
|
2011-09-11 14:26:23 +04:00
|
|
|
this->nodecache.clear();
|
|
|
|
this->nodeidcache.clear();
|
2010-04-12 04:16:36 +04:00
|
|
|
NodeDumper dumper(this->nodecache, false);
|
|
|
|
Traverser trav(dumper, *this->root_node, Traverser::PRE_AND_POSTFIX);
|
|
|
|
trav.execute();
|
|
|
|
assert(this->nodecache.contains(*this->root_node) &&
|
|
|
|
"NodeDumper failed to create a cache");
|
|
|
|
}
|
2011-09-11 11:10:31 +04:00
|
|
|
return this->nodecache[node];
|
2010-04-12 04:16:36 +04:00
|
|
|
}
|
2010-11-06 18:04:03 +03:00
|
|
|
|
2011-09-11 12:51:55 +04:00
|
|
|
static bool filter(char c)
|
|
|
|
{
|
|
|
|
return c == ' ' || c == '\n' || c == '\t' || c == '\r';
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Returns the cached ID string representation of the subtree rooted by \a node.
|
|
|
|
If node is not cached, the cache will be rebuilt.
|
|
|
|
|
|
|
|
The difference between this method and getString() is that the ID string
|
|
|
|
is stripped for whitespace. Especially indentation whitespace is important to
|
|
|
|
strip to enable cache hits for equivalent nodes from different scopes.
|
|
|
|
*/
|
|
|
|
const std::string &Tree::getIdString(const AbstractNode &node) const
|
|
|
|
{
|
|
|
|
assert(this->root_node);
|
|
|
|
if (!this->nodeidcache.contains(node)) {
|
|
|
|
std::string str = getString(node);
|
|
|
|
str.erase(std::remove_if(str.begin(), str.end(), filter), str.end());
|
|
|
|
return this->nodeidcache.insert(node, str);
|
|
|
|
}
|
|
|
|
return this->nodeidcache[node];
|
|
|
|
}
|
|
|
|
|
2010-11-06 18:04:03 +03:00
|
|
|
/*!
|
|
|
|
Sets a new root. Will clear the existing cache.
|
|
|
|
*/
|
|
|
|
void Tree::setRoot(const AbstractNode *root)
|
|
|
|
{
|
|
|
|
this->root_node = root;
|
|
|
|
this->nodecache.clear();
|
|
|
|
}
|