You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
566 lines
12 KiB
566 lines
12 KiB
ANTLR_BEGIN_NAMESPACE()
|
|
|
|
template<class ImplTraits>
|
|
CommonTree<ImplTraits>::CommonTree()
|
|
{
|
|
m_savedIndex = 0;
|
|
m_startIndex = 0;
|
|
m_stopIndex = 0;
|
|
m_token = NULL;
|
|
m_parent = NULL;
|
|
m_childIndex = 0;
|
|
}
|
|
|
|
template<class ImplTraits>
|
|
CommonTree<ImplTraits>::CommonTree( const CommonTree& ctree )
|
|
:m_children( ctree.m_children)
|
|
{
|
|
m_savedIndex = ctree.m_savedIndex;
|
|
m_startIndex = ctree.m_startIndex;
|
|
m_stopIndex = ctree.m_stopIndex;
|
|
m_token = ctree.m_token;
|
|
m_parent = ctree.m_parent;
|
|
m_childIndex = ctree.m_childIndex;
|
|
}
|
|
|
|
template<class ImplTraits>
|
|
CommonTree<ImplTraits>::CommonTree( CommonTokenType* token )
|
|
{
|
|
m_savedIndex = 0;
|
|
m_startIndex = 0;
|
|
m_stopIndex = 0;
|
|
m_token = token;
|
|
m_parent = NULL;
|
|
m_childIndex = 0;
|
|
}
|
|
|
|
template<class ImplTraits>
|
|
CommonTree<ImplTraits>::CommonTree( CommonTree* tree )
|
|
{
|
|
m_savedIndex = 0;
|
|
m_startIndex = 0;
|
|
m_stopIndex = 0;
|
|
m_token = tree->get_token();
|
|
m_parent = NULL;
|
|
m_childIndex = 0;
|
|
}
|
|
|
|
template<class ImplTraits>
|
|
typename CommonTree<ImplTraits>::TokenType* CommonTree<ImplTraits>::get_token() const
|
|
{
|
|
return m_token;
|
|
}
|
|
|
|
template<class ImplTraits>
|
|
typename CommonTree<ImplTraits>::ChildrenType& CommonTree<ImplTraits>::get_children()
|
|
{
|
|
return m_children;
|
|
}
|
|
|
|
template<class ImplTraits>
|
|
const typename CommonTree<ImplTraits>::ChildrenType& CommonTree<ImplTraits>::get_children() const
|
|
{
|
|
return m_children;
|
|
}
|
|
|
|
template<class ImplTraits>
|
|
typename CommonTree<ImplTraits>::ChildrenType* CommonTree<ImplTraits>::get_children_p()
|
|
{
|
|
return &m_children;
|
|
}
|
|
|
|
template<class ImplTraits>
|
|
void CommonTree<ImplTraits>::addChild(TreeType* child)
|
|
{
|
|
ANTLR_UINT32 n;
|
|
ANTLR_UINT32 i;
|
|
|
|
if (child == NULL)
|
|
return;
|
|
|
|
ChildrenType& child_children = child->get_children();
|
|
ChildrenType& tree_children = this->get_children();
|
|
|
|
if (child->isNilNode() == true)
|
|
{
|
|
if ( !child_children.empty() && child_children == tree_children )
|
|
{
|
|
// TODO: Change to exception rather than ANTLR3_FPRINTF?
|
|
//
|
|
fprintf(stderr, "ANTLR3: An attempt was made to add a child list to itself!\n");
|
|
return;
|
|
}
|
|
|
|
// Add all of the children's children to this list
|
|
//
|
|
if ( !child_children.empty() )
|
|
{
|
|
if (tree_children.empty())
|
|
{
|
|
// We are build ing the tree structure here, so we need not
|
|
// worry about duplication of pointers as the tree node
|
|
// factory will only clean up each node once. So we just
|
|
// copy in the child's children pointer as the child is
|
|
// a nil node (has not root itself).
|
|
//
|
|
tree_children.swap( child_children );
|
|
this->freshenPACIndexesAll();
|
|
}
|
|
else
|
|
{
|
|
// Need to copy the children
|
|
//
|
|
n = child_children.size();
|
|
|
|
for (i = 0; i < n; i++)
|
|
{
|
|
TreeType* entry;
|
|
entry = child_children[i];
|
|
|
|
// ANTLR3 lists can be sparse, unlike Array Lists
|
|
//
|
|
if (entry != NULL)
|
|
{
|
|
tree_children.push_back(entry);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Tree we are adding is not a Nil and might have children to copy
|
|
//
|
|
if (tree_children.empty())
|
|
{
|
|
// No children in the tree we are adding to, so create a new list on
|
|
// the fly to hold them.
|
|
//
|
|
this->createChildrenList();
|
|
}
|
|
tree_children.push_back( child );
|
|
}
|
|
}
|
|
|
|
template<class ImplTraits>
|
|
void CommonTree<ImplTraits>::addChildren(const ChildListType& kids)
|
|
{
|
|
for( typename ChildListType::const_iterator iter = kids.begin();
|
|
iter != kids.end(); ++iter )
|
|
{
|
|
this->addChild( *iter );
|
|
}
|
|
}
|
|
|
|
//dummy one, as vector is always there
|
|
template<class ImplTraits>
|
|
void CommonTree<ImplTraits>::createChildrenList()
|
|
{
|
|
}
|
|
|
|
template<class ImplTraits>
|
|
typename CommonTree<ImplTraits>::TreeType* CommonTree<ImplTraits>::deleteChild(ANTLR_UINT32 i)
|
|
{
|
|
if( m_children.empty() )
|
|
return NULL;
|
|
|
|
return m_children.erase( m_children.begin() + i);
|
|
}
|
|
|
|
template<class ImplTraits>
|
|
void CommonTree<ImplTraits>::replaceChildren(ANTLR_INT32 startChildIndex, ANTLR_INT32 stopChildIndex, TreeType* newTree)
|
|
{
|
|
ANTLR_INT32 replacingHowMany; // How many nodes will go away
|
|
ANTLR_INT32 replacingWithHowMany; // How many nodes will replace them
|
|
ANTLR_INT32 numNewChildren; // Tracking variable
|
|
ANTLR_INT32 delta; // Difference in new vs existing count
|
|
|
|
ANTLR_INT32 i;
|
|
ANTLR_INT32 j;
|
|
|
|
if ( m_children.empty() )
|
|
{
|
|
fprintf(stderr, "replaceChildren call: Indexes are invalid; no children in list for %s", this->getText().c_str() );
|
|
return;
|
|
}
|
|
|
|
// Either use the existing list of children in the supplied nil node, or build a vector of the
|
|
// tree we were given if it is not a nil node, then we treat both situations exactly the same
|
|
//
|
|
ChildrenType newChildren_temp;
|
|
ChildrenType* newChildren; // Iterator for whatever we are going to add in
|
|
|
|
if (newTree->isNilNode())
|
|
{
|
|
newChildren = newTree->get_children_p();
|
|
}
|
|
else
|
|
{
|
|
newChildren = &newChildren_temp;
|
|
newChildren->push_back(newTree);
|
|
}
|
|
|
|
// Initialize
|
|
//
|
|
replacingHowMany = stopChildIndex - startChildIndex + 1;
|
|
replacingWithHowMany = newChildren->size();
|
|
delta = replacingHowMany - replacingWithHowMany;
|
|
numNewChildren = newChildren->size();
|
|
|
|
// If it is the same number of nodes, then do a direct replacement
|
|
//
|
|
if (delta == 0)
|
|
{
|
|
TreeType* child;
|
|
|
|
// Same number of nodes
|
|
//
|
|
j = 0;
|
|
for (i = startChildIndex; i <= stopChildIndex; i++)
|
|
{
|
|
child = newChildren->at(j);
|
|
ChildrenType& parent_children = this->get_children();
|
|
parent_children[i] = child;
|
|
child->setParent(this);
|
|
child->setChildIndex(i);
|
|
}
|
|
}
|
|
else if (delta > 0)
|
|
{
|
|
ANTLR_UINT32 indexToDelete;
|
|
|
|
// Less nodes than there were before
|
|
// reuse what we have then delete the rest
|
|
//
|
|
ChildrenType& parent_children = this->get_children();
|
|
for (j = 0; j < numNewChildren; j++)
|
|
{
|
|
parent_children[ startChildIndex + j ] = newChildren->at(j);
|
|
}
|
|
|
|
// We just delete the same index position until done
|
|
//
|
|
indexToDelete = startChildIndex + numNewChildren;
|
|
|
|
for (j = indexToDelete; j <= stopChildIndex; j++)
|
|
{
|
|
parent_children.erase( parent_children.begin() + indexToDelete);
|
|
}
|
|
|
|
this->freshenPACIndexes(startChildIndex);
|
|
}
|
|
else
|
|
{
|
|
ChildrenType& parent_children = this->get_children();
|
|
ANTLR_UINT32 numToInsert;
|
|
|
|
// More nodes than there were before
|
|
// Use what we can, then start adding
|
|
//
|
|
for (j = 0; j < replacingHowMany; j++)
|
|
{
|
|
parent_children[ startChildIndex + j ] = newChildren->at(j);
|
|
}
|
|
|
|
numToInsert = replacingWithHowMany - replacingHowMany;
|
|
|
|
for (j = replacingHowMany; j < replacingWithHowMany; j++)
|
|
{
|
|
parent_children.push_back( newChildren->at(j) );
|
|
}
|
|
|
|
this->freshenPACIndexes(startChildIndex);
|
|
}
|
|
}
|
|
|
|
template<class ImplTraits>
|
|
CommonTree<ImplTraits>* CommonTree<ImplTraits>::dupNode() const
|
|
{
|
|
// The node we are duplicating is in fact the common tree (that's why we are here)
|
|
// so we use the super pointer to duplicate.
|
|
//
|
|
TreeType* clone = new TreeType();
|
|
|
|
// The pointer we return is the base implementation of course
|
|
//
|
|
clone->set_token( m_token );
|
|
return clone;
|
|
}
|
|
|
|
template<class ImplTraits>
|
|
typename CommonTree<ImplTraits>::TreeType* CommonTree<ImplTraits>::dupTree()
|
|
{
|
|
TreeType* newTree;
|
|
ANTLR_UINT32 i;
|
|
ANTLR_UINT32 s;
|
|
|
|
newTree = this->dupNode();
|
|
|
|
if ( !m_children.empty() )
|
|
{
|
|
s = m_children.size();
|
|
|
|
for (i = 0; i < s; i++)
|
|
{
|
|
TreeType* t;
|
|
TreeType* newNode;
|
|
|
|
t = m_children[i];
|
|
|
|
if (t!= NULL)
|
|
{
|
|
newNode = t->dupTree();
|
|
newTree->addChild(newNode);
|
|
}
|
|
}
|
|
}
|
|
|
|
return newTree;
|
|
}
|
|
|
|
template<class ImplTraits>
|
|
ANTLR_UINT32 CommonTree<ImplTraits>::getCharPositionInLine()
|
|
{
|
|
CommonTokenType* token;
|
|
token = m_token;
|
|
|
|
if (token == NULL || (token->getCharPositionInLine() == -1) )
|
|
{
|
|
if (this->getChildCount() > 0)
|
|
{
|
|
TreeType* child;
|
|
|
|
child = this->getChild(0);
|
|
|
|
return child->getCharPositionInLine();
|
|
}
|
|
return 0;
|
|
}
|
|
return token->getCharPositionInLine();
|
|
}
|
|
|
|
template<class ImplTraits>
|
|
typename CommonTree<ImplTraits>::TreeType* CommonTree<ImplTraits>::getChild(ANTLR_UINT32 i)
|
|
{
|
|
if ( m_children.empty()
|
|
|| i >= m_children.size() )
|
|
{
|
|
return NULL;
|
|
}
|
|
return m_children[i];
|
|
|
|
}
|
|
|
|
template<class ImplTraits>
|
|
void CommonTree<ImplTraits>::set_childIndex( ANTLR_INT32 i)
|
|
{
|
|
m_childIndex = i;
|
|
}
|
|
|
|
template<class ImplTraits>
|
|
ANTLR_INT32 CommonTree<ImplTraits>::get_childIndex() const
|
|
{
|
|
return m_childIndex;
|
|
}
|
|
|
|
template<class ImplTraits>
|
|
ANTLR_UINT32 CommonTree<ImplTraits>::getChildCount() const
|
|
{
|
|
return static_cast<ANTLR_UINT32>( m_children.size() );
|
|
}
|
|
|
|
template<class ImplTraits>
|
|
typename CommonTree<ImplTraits>::TreeType* CommonTree<ImplTraits>::get_parent() const
|
|
{
|
|
return m_parent;
|
|
}
|
|
|
|
template<class ImplTraits>
|
|
void CommonTree<ImplTraits>::set_parent( TreeType* parent)
|
|
{
|
|
m_parent = parent;
|
|
}
|
|
|
|
template<class ImplTraits>
|
|
ANTLR_UINT32 CommonTree<ImplTraits>::getType()
|
|
{
|
|
if (this == NULL)
|
|
{
|
|
return 0;
|
|
}
|
|
else
|
|
{
|
|
return m_token->getType();
|
|
}
|
|
}
|
|
|
|
template<class ImplTraits>
|
|
typename CommonTree<ImplTraits>::TreeType* CommonTree<ImplTraits>::getFirstChildWithType(ANTLR_UINT32 type)
|
|
{
|
|
ANTLR_UINT32 i;
|
|
std::size_t cs;
|
|
|
|
TreeType* t;
|
|
if ( !m_children.empty() )
|
|
{
|
|
cs = m_children.size();
|
|
for (i = 0; i < cs; i++)
|
|
{
|
|
t = m_children[i];
|
|
if (t->getType() == type)
|
|
{
|
|
return t;
|
|
}
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
template<class ImplTraits>
|
|
ANTLR_UINT32 CommonTree<ImplTraits>::getLine()
|
|
{
|
|
TreeType* cTree = this;
|
|
CommonTokenType* token;
|
|
token = cTree->get_token();
|
|
|
|
if (token == NULL || token->getLine() == 0)
|
|
{
|
|
if ( this->getChildCount() > 0)
|
|
{
|
|
TreeType* child;
|
|
child = this->getChild(0);
|
|
return child->getLine();
|
|
}
|
|
return 0;
|
|
}
|
|
return token->getLine();
|
|
}
|
|
|
|
template<class ImplTraits>
|
|
typename CommonTree<ImplTraits>::StringType CommonTree<ImplTraits>::getText()
|
|
{
|
|
return this->toString();
|
|
}
|
|
|
|
template<class ImplTraits>
|
|
bool CommonTree<ImplTraits>::isNilNode()
|
|
{
|
|
// This is a Nil tree if it has no payload (Token in our case)
|
|
//
|
|
if(m_token == NULL)
|
|
{
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
template<class ImplTraits>
|
|
void CommonTree<ImplTraits>::setChild(ANTLR_UINT32 i, TreeType* child)
|
|
{
|
|
if( m_children.size() >= i )
|
|
m_children.resize(i+1);
|
|
m_children[i] = child;
|
|
}
|
|
|
|
template<class ImplTraits>
|
|
typename CommonTree<ImplTraits>::StringType CommonTree<ImplTraits>::toStringTree()
|
|
{
|
|
StringType string;
|
|
ANTLR_UINT32 i;
|
|
ANTLR_UINT32 n;
|
|
TreeType* t;
|
|
|
|
if( m_children.empty() )
|
|
{
|
|
return this->toString();
|
|
}
|
|
|
|
/* Need a new string with nothing at all in it.
|
|
*/
|
|
if (this->isNilNode() == false)
|
|
{
|
|
string.append("(");
|
|
string.append(this->toString());
|
|
string.append(" ");
|
|
}
|
|
if ( m_children != NULL)
|
|
{
|
|
n = m_children.size();
|
|
|
|
for (i = 0; i < n; i++)
|
|
{
|
|
t = m_children[i];
|
|
|
|
if (i > 0)
|
|
{
|
|
string.append(" ");
|
|
}
|
|
string.append(t->toStringTree());
|
|
}
|
|
}
|
|
if (this->isNilNode() == false)
|
|
{
|
|
string.append(")");
|
|
}
|
|
|
|
return string;
|
|
}
|
|
|
|
template<class ImplTraits>
|
|
typename CommonTree<ImplTraits>::StringType CommonTree<ImplTraits>::toString()
|
|
{
|
|
if (this->isNilNode() )
|
|
{
|
|
StringType nilNode;
|
|
|
|
nilNode = "nil";
|
|
|
|
return nilNode;
|
|
}
|
|
|
|
return m_token->getText();
|
|
}
|
|
|
|
template<class ImplTraits>
|
|
void CommonTree<ImplTraits>::freshenPACIndexesAll()
|
|
{
|
|
this->freshenPACIndexes(0);
|
|
}
|
|
|
|
template<class ImplTraits>
|
|
void CommonTree<ImplTraits>::freshenPACIndexes(ANTLR_UINT32 offset)
|
|
{
|
|
ANTLR_UINT32 count;
|
|
ANTLR_UINT32 c;
|
|
|
|
count = this->getChildCount(); // How many children do we have
|
|
|
|
// Loop from the supplied index and set the indexes and parent
|
|
//
|
|
for (c = offset; c < count; c++)
|
|
{
|
|
TreeType* child;
|
|
|
|
child = this->getChild(c);
|
|
|
|
child->setChildIndex(c);
|
|
child->setParent(this);
|
|
}
|
|
}
|
|
|
|
template<class ImplTraits>
|
|
void CommonTree<ImplTraits>::reuse()
|
|
{
|
|
delete this; //memory re-use should be taken by the library user
|
|
}
|
|
|
|
template<class ImplTraits>
|
|
CommonTree<ImplTraits>::~CommonTree()
|
|
{
|
|
}
|
|
|
|
ANTLR_END_NAMESPACE()
|