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.
423 lines
8.8 KiB
423 lines
8.8 KiB
ANTLR_BEGIN_NAMESPACE()
|
|
|
|
template<class ImplTraits>
|
|
CommonTreeNodeStream<ImplTraits>::CommonTreeNodeStream(ANTLR_UINT32 hint)
|
|
{
|
|
this->init(hint);
|
|
}
|
|
|
|
template<class ImplTraits>
|
|
void CommonTreeNodeStream<ImplTraits>::init( ANTLR_UINT32 hint )
|
|
{
|
|
m_root = NULL;
|
|
m_adaptor = new TreeAdaptorType;
|
|
// Create the node list map
|
|
//
|
|
if (hint == 0)
|
|
hint = DEFAULT_INITIAL_BUFFER_SIZE;
|
|
m_nodes.reserve( DEFAULT_INITIAL_BUFFER_SIZE );
|
|
|
|
m_p = -1;
|
|
m_currentNode = NULL;
|
|
m_previousNode = NULL;
|
|
m_currentChildIndex = 0;
|
|
m_absoluteNodeIndex = 0;
|
|
m_lookAhead = NULL;
|
|
m_lookAheadLength = 0;
|
|
m_head = 0;
|
|
m_tail = 0;
|
|
m_uniqueNavigationNodes = false;
|
|
m_isRewriter = false;
|
|
|
|
CommonTokenType* token = new CommonTokenType(CommonTokenType::TOKEN_UP);
|
|
token->set_tokText( "UP" );
|
|
m_UP.set_token( token );
|
|
|
|
token = new CommonTokenType(CommonTokenType::TOKEN_DOWN);
|
|
token->set_tokText( "DOWN" );
|
|
m_DOWN.set_token( token );
|
|
|
|
token = new CommonTokenType(CommonTokenType::TOKEN_EOF);
|
|
token->set_tokText( "EOF" );
|
|
m_EOF_NODE.set_token( token );
|
|
|
|
token = new CommonTokenType(CommonTokenType::TOKEN_INVALID);
|
|
token->set_tokText( "INVALID" );
|
|
m_EOF_NODE.set_token( token );
|
|
}
|
|
|
|
template<class ImplTraits>
|
|
CommonTreeNodeStream<ImplTraits>::CommonTreeNodeStream( const CommonTreeNodeStream& ctn )
|
|
{
|
|
m_root = ctn.m_root;
|
|
m_adaptor = ctn.m_adaptor;
|
|
m_nodes.reserve( DEFAULT_INITIAL_BUFFER_SIZE );
|
|
m_nodeStack = ctn.m_nodeStack;
|
|
m_p = -1;
|
|
m_currentNode = NULL;
|
|
m_previousNode = NULL;
|
|
m_currentChildIndex = 0;
|
|
m_absoluteNodeIndex = 0;
|
|
m_lookAhead = NULL;
|
|
m_lookAheadLength = 0;
|
|
m_head = 0;
|
|
m_tail = 0;
|
|
m_uniqueNavigationNodes = false;
|
|
m_isRewriter = true;
|
|
|
|
m_UP.set_token( ctn.m_UP.get_token() );
|
|
m_DOWN.set_token( ctn.m_DOWN.get_token() );
|
|
m_EOF_NODE.set_token( ctn.m_EOF_NODE.get_token() );
|
|
m_INVALID_NODE.set_token( ctn.m_INVALID_NODE.get_token() );
|
|
}
|
|
|
|
template<class ImplTraits>
|
|
CommonTreeNodeStream<ImplTraits>::CommonTreeNodeStream( TreeType* tree, ANTLR_UINT32 hint )
|
|
{
|
|
this->init(hint);
|
|
m_root = tree;
|
|
}
|
|
|
|
template<class ImplTraits>
|
|
CommonTreeNodeStream<ImplTraits>::~CommonTreeNodeStream()
|
|
{
|
|
// If this is a rewrting stream, then certain resources
|
|
// belong to the originating node stream and we do not
|
|
// free them here.
|
|
//
|
|
if ( m_isRewriter != true)
|
|
{
|
|
delete m_adaptor;
|
|
|
|
m_nodeStack.clear();
|
|
|
|
delete m_INVALID_NODE.get_token();
|
|
delete m_EOF_NODE.get_token();
|
|
delete m_DOWN.get_token();
|
|
delete m_UP.get_token();
|
|
}
|
|
|
|
m_nodes.clear();
|
|
}
|
|
|
|
template<class ImplTraits>
|
|
typename CommonTreeNodeStream<ImplTraits>::TreeType* CommonTreeNodeStream<ImplTraits>::_LT(ANTLR_INT32 k)
|
|
{
|
|
if ( m_p == -1)
|
|
{
|
|
this->fillBufferRoot();
|
|
}
|
|
|
|
if (k < 0)
|
|
{
|
|
return this->LB(-k);
|
|
}
|
|
else if (k == 0)
|
|
{
|
|
return &(m_INVALID_NODE);
|
|
}
|
|
|
|
// k was a legitimate request,
|
|
//
|
|
if (( m_p + k - 1) >= (ANTLR_INT32)(m_nodes.size()))
|
|
{
|
|
return &(m_EOF_NODE);
|
|
}
|
|
|
|
return m_nodes[ m_p + k - 1 ];
|
|
}
|
|
|
|
template<class ImplTraits>
|
|
typename CommonTreeNodeStream<ImplTraits>::TreeType* CommonTreeNodeStream<ImplTraits>::getTreeSource()
|
|
{
|
|
return m_root;
|
|
}
|
|
|
|
template<class ImplTraits>
|
|
typename CommonTreeNodeStream<ImplTraits>::TreeAdaptorType* CommonTreeNodeStream<ImplTraits>::getTreeAdaptor()
|
|
{
|
|
return m_adaptor;
|
|
}
|
|
|
|
template<class ImplTraits>
|
|
void CommonTreeNodeStream<ImplTraits>::set_uniqueNavigationNodes(bool uniqueNavigationNodes)
|
|
{
|
|
m_uniqueNavigationNodes = uniqueNavigationNodes;
|
|
}
|
|
|
|
template<class ImplTraits>
|
|
typename CommonTreeNodeStream<ImplTraits>::StringType CommonTreeNodeStream<ImplTraits>::toString()
|
|
{
|
|
return this->toStringSS(m_root, NULL);
|
|
}
|
|
|
|
template<class ImplTraits>
|
|
typename CommonTreeNodeStream<ImplTraits>::StringType CommonTreeNodeStream<ImplTraits>::toStringSS(TreeType* start, TreeType* stop)
|
|
{
|
|
StringType buf;
|
|
this->toStringWork(start, stop, buf);
|
|
return buf;
|
|
}
|
|
|
|
template<class ImplTraits>
|
|
void CommonTreeNodeStream<ImplTraits>::toStringWork(TreeType* start, TreeType* stop, StringType& str)
|
|
{
|
|
ANTLR_UINT32 n;
|
|
ANTLR_UINT32 c;
|
|
StringStreamType buf;
|
|
|
|
if (!start->isNilNode() )
|
|
{
|
|
StringType text;
|
|
|
|
text = start->toString();
|
|
|
|
if (text.empty())
|
|
{
|
|
buf << ' ';
|
|
buf << start->getType();
|
|
}
|
|
else
|
|
buf << text;
|
|
}
|
|
|
|
if (start == stop)
|
|
{
|
|
return; /* Finished */
|
|
}
|
|
|
|
n = start->getChildCount();
|
|
|
|
if (n > 0 && ! start->isNilNode() )
|
|
{
|
|
buf << ' ';
|
|
buf << CommonTokenType::TOKEN_DOWN;
|
|
}
|
|
|
|
for (c = 0; c<n ; c++)
|
|
{
|
|
TreeType* child;
|
|
|
|
child = start->getChild(c);
|
|
this->toStringWork(child, stop, buf);
|
|
}
|
|
|
|
if (n > 0 && ! start->isNilNode() )
|
|
{
|
|
buf << ' ';
|
|
buf << CommonTokenType::TOKEN_UP;
|
|
}
|
|
str = buf.str();
|
|
}
|
|
|
|
template<class ImplTraits>
|
|
typename CommonTreeNodeStream<ImplTraits>::TreeType* CommonTreeNodeStream<ImplTraits>::get(ANTLR_INT32 k)
|
|
{
|
|
if( m_p == -1 )
|
|
{
|
|
this->fillBufferRoot();
|
|
}
|
|
|
|
return m_nodes[k];
|
|
}
|
|
|
|
template<class ImplTraits>
|
|
void CommonTreeNodeStream<ImplTraits>::replaceChildren(TreeType* parent,
|
|
ANTLR_INT32 startChildIndex,
|
|
ANTLR_INT32 stopChildIndex,
|
|
TreeType* t)
|
|
{
|
|
if (parent != NULL)
|
|
{
|
|
TreeAdaptorType* adaptor;
|
|
adaptor = this->getTreeAdaptor();
|
|
adaptor->replaceChildren(parent, startChildIndex, stopChildIndex, t);
|
|
}
|
|
}
|
|
|
|
template<class ImplTraits>
|
|
typename CommonTreeNodeStream<ImplTraits>::TreeType* CommonTreeNodeStream<ImplTraits>::LB(ANTLR_INT32 k)
|
|
{
|
|
if ( k==0)
|
|
{
|
|
return &(m_INVALID_NODE);
|
|
}
|
|
|
|
if ( (m_p - k) < 0)
|
|
{
|
|
return &(m_INVALID_NODE);
|
|
}
|
|
|
|
return m_nodes[ m_p - k ];
|
|
}
|
|
|
|
template<class ImplTraits>
|
|
void CommonTreeNodeStream<ImplTraits>::addNavigationNode(ANTLR_UINT32 ttype)
|
|
{
|
|
TreeType* node;
|
|
|
|
node = NULL;
|
|
|
|
if (ttype == CommonTokenType::TOKEN_DOWN)
|
|
{
|
|
if (this->hasUniqueNavigationNodes() == true)
|
|
{
|
|
node = this->newDownNode();
|
|
}
|
|
else
|
|
{
|
|
node = &m_DOWN;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (this->hasUniqueNavigationNodes() == true)
|
|
{
|
|
node = this->newUpNode();
|
|
}
|
|
else
|
|
{
|
|
node = &m_UP;
|
|
}
|
|
}
|
|
|
|
// Now add the node we decided upon.
|
|
//
|
|
m_nodes.push_back(node);
|
|
}
|
|
|
|
template<class ImplTraits>
|
|
typename CommonTreeNodeStream<ImplTraits>::TreeType* CommonTreeNodeStream<ImplTraits>::newDownNode()
|
|
{
|
|
TreeType* dNode;
|
|
CommonTokenType* token;
|
|
|
|
token = new CommonTokenType(CommonTokenType::TOKEN_DOWN);
|
|
token->set_tokText("DOWN");
|
|
dNode = new TreeType(token);
|
|
return &dNode;
|
|
}
|
|
|
|
template<class ImplTraits>
|
|
typename CommonTreeNodeStream<ImplTraits>::TreeType* CommonTreeNodeStream<ImplTraits>::newUpNode()
|
|
{
|
|
TreeType* uNode;
|
|
CommonTokenType* token;
|
|
|
|
token = new CommonTokenType(CommonTokenType::TOKEN_UP);
|
|
token->set_tokText("UP");
|
|
uNode = new TreeType(token);
|
|
return &uNode;
|
|
|
|
}
|
|
|
|
template<class ImplTraits>
|
|
bool CommonTreeNodeStream<ImplTraits>::hasUniqueNavigationNodes() const
|
|
{
|
|
return m_uniqueNavigationNodes;
|
|
}
|
|
|
|
template<class ImplTraits>
|
|
ANTLR_UINT32 CommonTreeNodeStream<ImplTraits>::getLookaheadSize()
|
|
{
|
|
return m_tail < m_head
|
|
? (m_lookAheadLength - m_head + m_tail)
|
|
: (m_tail - m_head);
|
|
}
|
|
|
|
template<class ImplTraits>
|
|
void CommonTreeNodeStream<ImplTraits>::push(ANTLR_INT32 index)
|
|
{
|
|
m_nodeStack.push(m_p); // Save current index
|
|
this->seek(index);
|
|
}
|
|
|
|
template<class ImplTraits>
|
|
ANTLR_INT32 CommonTreeNodeStream<ImplTraits>::pop()
|
|
{
|
|
ANTLR_INT32 retVal;
|
|
|
|
retVal = m_nodeStack.top();
|
|
m_nodeStack.pop();
|
|
this->seek(retVal);
|
|
return retVal;
|
|
}
|
|
|
|
template<class ImplTraits>
|
|
void CommonTreeNodeStream<ImplTraits>::reset()
|
|
{
|
|
if ( m_p != -1)
|
|
{
|
|
m_p = 0;
|
|
}
|
|
BaseType::m_lastMarker = 0;
|
|
|
|
|
|
// Free and reset the node stack only if this is not
|
|
// a rewriter, which is going to reuse the originating
|
|
// node streams node stack
|
|
//
|
|
if (m_isRewriter != true)
|
|
m_nodeStack.clear();
|
|
}
|
|
|
|
template<class ImplTraits>
|
|
void CommonTreeNodeStream<ImplTraits>::fillBufferRoot()
|
|
{
|
|
// Call the generic buffer routine with the root as the
|
|
// argument
|
|
//
|
|
this->fillBuffer(m_root);
|
|
m_p = 0; // Indicate we are at buffer start
|
|
}
|
|
|
|
template<class ImplTraits>
|
|
void CommonTreeNodeStream<ImplTraits>::fillBuffer(TreeType* t)
|
|
{
|
|
bool nilNode;
|
|
ANTLR_UINT32 nCount;
|
|
ANTLR_UINT32 c;
|
|
|
|
nilNode = m_adaptor->isNilNode(t);
|
|
|
|
// If the supplied node is not a nil (list) node then we
|
|
// add in the node itself to the vector
|
|
//
|
|
if (nilNode == false)
|
|
{
|
|
m_nodes.push_back(t);
|
|
}
|
|
|
|
// Only add a DOWN node if the tree is not a nil tree and
|
|
// the tree does have children.
|
|
//
|
|
nCount = t->getChildCount();
|
|
|
|
if (nilNode == false && nCount>0)
|
|
{
|
|
this->addNavigationNode( CommonTokenType::TOKEN_DOWN);
|
|
}
|
|
|
|
// We always add any children the tree contains, which is
|
|
// a recursive call to this function, which will cause similar
|
|
// recursion and implement a depth first addition
|
|
//
|
|
for (c = 0; c < nCount; c++)
|
|
{
|
|
this->fillBuffer( m_adaptor->getChild(t, c));
|
|
}
|
|
|
|
// If the tree had children and was not a nil (list) node, then we
|
|
// we need to add an UP node here to match the DOWN node
|
|
//
|
|
if (nilNode == false && nCount > 0)
|
|
{
|
|
this->addNavigationNode(CommonTokenType::TOKEN_UP);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
ANTLR_END_NAMESPACE()
|
|
|