ANTLR_BEGIN_NAMESPACE() template CommonTree::CommonTree() { m_savedIndex = 0; m_startIndex = 0; m_stopIndex = 0; m_token = NULL; m_parent = NULL; m_childIndex = 0; } template CommonTree::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 CommonTree::CommonTree( CommonTokenType* token ) { m_savedIndex = 0; m_startIndex = 0; m_stopIndex = 0; m_token = token; m_parent = NULL; m_childIndex = 0; } template CommonTree::CommonTree( CommonTree* tree ) { m_savedIndex = 0; m_startIndex = 0; m_stopIndex = 0; m_token = tree->get_token(); m_parent = NULL; m_childIndex = 0; } template typename CommonTree::TokenType* CommonTree::get_token() const { return m_token; } template typename CommonTree::ChildrenType& CommonTree::get_children() { return m_children; } template const typename CommonTree::ChildrenType& CommonTree::get_children() const { return m_children; } template typename CommonTree::ChildrenType* CommonTree::get_children_p() { return &m_children; } template void CommonTree::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 void CommonTree::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 void CommonTree::createChildrenList() { } template typename CommonTree::TreeType* CommonTree::deleteChild(ANTLR_UINT32 i) { if( m_children.empty() ) return NULL; return m_children.erase( m_children.begin() + i); } template void CommonTree::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 CommonTree* CommonTree::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 typename CommonTree::TreeType* CommonTree::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 ANTLR_UINT32 CommonTree::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 typename CommonTree::TreeType* CommonTree::getChild(ANTLR_UINT32 i) { if ( m_children.empty() || i >= m_children.size() ) { return NULL; } return m_children[i]; } template void CommonTree::set_childIndex( ANTLR_INT32 i) { m_childIndex = i; } template ANTLR_INT32 CommonTree::get_childIndex() const { return m_childIndex; } template ANTLR_UINT32 CommonTree::getChildCount() const { return static_cast( m_children.size() ); } template typename CommonTree::TreeType* CommonTree::get_parent() const { return m_parent; } template void CommonTree::set_parent( TreeType* parent) { m_parent = parent; } template ANTLR_UINT32 CommonTree::getType() { if (this == NULL) { return 0; } else { return m_token->getType(); } } template typename CommonTree::TreeType* CommonTree::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 ANTLR_UINT32 CommonTree::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 typename CommonTree::StringType CommonTree::getText() { return this->toString(); } template bool CommonTree::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 void CommonTree::setChild(ANTLR_UINT32 i, TreeType* child) { if( m_children.size() >= i ) m_children.resize(i+1); m_children[i] = child; } template typename CommonTree::StringType CommonTree::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 typename CommonTree::StringType CommonTree::toString() { if (this->isNilNode() ) { StringType nilNode; nilNode = "nil"; return nilNode; } return m_token->getText(); } template void CommonTree::freshenPACIndexesAll() { this->freshenPACIndexes(0); } template void CommonTree::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 void CommonTree::reuse() { delete this; //memory re-use should be taken by the library user } template CommonTree::~CommonTree() { } ANTLR_END_NAMESPACE()