namespace antlr3 { template RewriteRuleElementStream::RewriteRuleElementStream(TreeAdaptorType* adaptor, const char* description) { this->init(adaptor, description); } template RewriteRuleElementStream::RewriteRuleElementStream(TreeAdaptorType* adaptor, const char* description, const ElementType* oneElement) { this->init(adaptor, description); if( oneElement != NULL ) this->add( oneElement ); } template RewriteRuleElementStream::RewriteRuleElementStream(TreeAdaptorType* adaptor, const char* description, const ElementsType& elements) : m_elements(elements) { this->init(adaptor, description); } template void RewriteRuleElementStream::init(TreeAdaptorType* adaptor, const char* description) { m_adaptor = adaptor; m_cursor = 0; m_dirty = false; } template RewriteRuleTokenStream::RewriteRuleTokenStream(TreeAdaptorType* adaptor, const char* description) //: BaseType(adaptor, description) { } template RewriteRuleTokenStream::RewriteRuleTokenStream(TreeAdaptorType* adaptor, const char* description, const TokenType* oneElement) //: BaseType(adaptor, description, oneElement) { } template RewriteRuleTokenStream::RewriteRuleTokenStream(TreeAdaptorType* adaptor, const char* description, const ElementsType& elements) //: BaseType(adaptor, description, elements) { } template RewriteRuleSubtreeStream::RewriteRuleSubtreeStream(TreeAdaptorType* adaptor, const char* description) //: BaseType(adaptor, description) { } template RewriteRuleSubtreeStream::RewriteRuleSubtreeStream(TreeAdaptorType* adaptor, const char* description, TreeTypePtr& oneElement) //: BaseType(adaptor, description, oneElement) { } template RewriteRuleSubtreeStream::RewriteRuleSubtreeStream(TreeAdaptorType* adaptor, const char* description, const ElementsType& elements) //: BaseType(adaptor, description, elements) { } /* template RewriteRuleNodeStream::RewriteRuleNodeStream(TreeAdaptorType* adaptor, const char* description) : BaseType(adaptor, description) { } template RewriteRuleNodeStream::RewriteRuleNodeStream(TreeAdaptorType* adaptor, const char* description, TokenType* oneElement) : BaseType(adaptor, description, oneElement) { } template RewriteRuleNodeStream::RewriteRuleNodeStream(TreeAdaptorType* adaptor, const char* description, const ElementsType& elements) : BaseType(adaptor, description, elements) { } */ template void RewriteRuleElementStream::reset() { m_cursor = 0; m_dirty = true; } template void RewriteRuleElementStream::add(ElementType* el) { if ( el== NULL ) return; m_elements.push_back(el); } template ElementType* RewriteRuleElementStream::_next() { ANTLR_UINT32 n = this->size(); if (n == 0) { // This means that the stream is empty return NULL; // Caller must cope with this (TODO throw RewriteEmptyStreamException) } // Traversed all the available elements already? if ( m_cursor >= n) // out of elements? { if (n == 1) { // Special case when size is single element, it will just dup a lot //return this->toTree(m_singleElement); return this->toTree(m_elements.at(0)); } // Out of elements and the size is not 1, so we cannot assume // that we just duplicate the entry n times (such as ID ent+ -> ^(ID ent)+) // This means we ran out of elements earlier than was expected. // return NULL; // Caller must cope with this (TODO throw RewriteEmptyStreamException) } // More than just a single element so we extract it from the // vector. ElementType* t = this->toTree(m_elements.at(m_cursor)); m_cursor++; return t; } template ElementType RewriteRuleElementStream::nextTree() { ANTLR_UINT32 n = this->size(); if ( m_dirty || ( (m_cursor >=n) && (n==1)) ) { // if out of elements and size is 1, dup ElementType* el = this->_next(); return this->dup(el); } // test size above then fetch ElementType* el = this->_next(); return el; } /* template typename RewriteRuleElementStream::TokenType* RewriteRuleElementStream::nextToken() { return this->_next(); } template typename RewriteRuleElementStream::TokenType* RewriteRuleElementStream::next() { ANTLR_UINT32 s; s = this->size(); if ( (m_cursor >= s) && (s == 1) ) { TreeTypePtr el; el = this->_next(); return this->dup(el); } return this->_next(); } */ template ElementType* RewriteRuleElementStream::dup( ElementType* element) { return dupImpl(element); } template ElementType* RewriteRuleElementStream::dupImpl( typename ImplTraits::CommonTokenType* element) { return NULL; // TODO throw here } template ElementType* RewriteRuleElementStream::dupImpl( typename ImplTraits::TreeTypePtr element) { return m_adaptor->dupTree(element); } template typename RewriteRuleSubtreeStream::TreeTypePtr RewriteRuleSubtreeStream::dup(TreeTypePtr element) { return this->dupTree(element); } template typename RewriteRuleSubtreeStream::TreeTypePtr RewriteRuleSubtreeStream::dupTree(TreeTypePtr element) { return BaseType::m_adaptor->dupNode(element); } template ElementType* RewriteRuleElementStream::toTree( ElementType* element) { return element; } /* template typename RewriteRuleNodeStream::TreeTypePtr RewriteRuleNodeStream::toTree(TreeTypePtr element) { return this->toTreeNode(element); } template typename RewriteRuleNodeStream::TreeTypePtr RewriteRuleNodeStream::toTreeNode(TreeTypePtr element) { return BaseType::m_adaptor->dupNode(element); } */ template bool RewriteRuleElementStream::hasNext() { if ( !m_elements.empty() && m_cursor < m_elements.size()) { return true; } else { return false; } } template typename RewriteRuleTokenStream::TreeTypePtr RewriteRuleTokenStream::nextNode() { TokenType *Token = this->nextToken(); //return BaseType::m_adaptor->create(Token); return m_adaptor->create(Token); } /* template typename RewriteRuleTokenStream::TreeTypePtr RewriteRuleTokenStream::nextNodeToken() { return BaseType::m_adaptor->create(this->_next()); } */ /// Number of elements available in the stream /// template ANTLR_UINT32 RewriteRuleElementStream::size() { return (ANTLR_UINT32)(m_elements.size()); } template typename RewriteRuleElementStream::StringType RewriteRuleElementStream::getDescription() { if ( m_elementDescription.empty() ) { m_elementDescription = ""; } return m_elementDescription; } template RewriteRuleElementStream::~RewriteRuleElementStream() { // Before placing the stream back in the pool, we // need to clear any vector it has. This is so any // free pointers that are associated with the // entries are called. However, if this particular function is called // then we know that the entries in the stream are definitely // tree nodes. Hence we check to see if any of them were nilNodes as // if they were, we can reuse them. // // We have some elements to traverse // for (ANTLR_UINT32 i = 0; i < m_elements.size(); i++) { ElementType *tree = m_elements.at(i); //if ( (tree != NULL) && tree->isNilNode() ) { // Had to remove this for now, check is not comprehensive enough // tree->reuse(tree); } } m_elements.clear(); } template typename RewriteRuleTokenStream::TokenType* RewriteRuleTokenStream::nextToken() { return this->_next(); } template typename RewriteRuleSubtreeStream::TreeTypePtr RewriteRuleSubtreeStream::nextNode(TreeTypePtr element) { //System.out.println("nextNode: elements="+elements+", singleElement="+((Tree)singleElement).toStringTree()); ANTLR_UINT32 n = this->size(); if ( BaseType::m_dirty || (BaseType::m_cursor>=n && n==1) ) { // if out of elements and size is 1, dup (at most a single node // since this is for making root nodes). TreeTypePtr el = this->_next(); return BaseType::m_adaptor->dupNode(el); } // test size above then fetch TreeType *tree = this->_next(); while (BaseType::m_adaptor.isNil(tree) && BaseType::m_adaptor.getChildCount(tree) == 1) tree = BaseType::m_adaptor->getChild(tree, 0); //System.out.println("_next="+((Tree)tree).toStringTree()); TreeType *el = BaseType::m_adaptor->dupNode(tree); // dup just the root (want node here) return el; } }