text: /** \file
   *  Implementation of the tree parser and overrides for the base recognizer
   */
  
  // [The "BSD licence"]
  // Copyright (c) 2005-2009 Jim Idle, Temporal Wave LLC
  // http://www.temporal-wave.com
  // http://www.linkedin.com/in/jimidle
  //
  // All rights reserved.
  //
  // Redistribution and use in source and binary forms, with or without
  // modification, are permitted provided that the following conditions
  // are met:
  // 1. Redistributions of source code must retain the above copyright
  //    notice, this list of conditions and the following disclaimer.
  // 2. Redistributions in binary form must reproduce the above copyright
  //    notice, this list of conditions and the following disclaimer in the
  //    documentation and/or other materials provided with the distribution.
  // 3. The name of the author may not be used to endorse or promote products
  //    derived from this software without specific prior written permission.
  //
  // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  // NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
  #include    <antlr3treeparser.h>
  
  /* BASE Recognizer overrides
   */
  static void				mismatch	    (pANTLR3_BASE_RECOGNIZER recognizer, ANTLR3_UINT32 ttype, pANTLR3_BITSET_LIST follow);
  
  /* Tree parser API
   */
  static void			setTreeNodeStream	    (pANTLR3_TREE_PARSER parser, pANTLR3_COMMON_TREE_NODE_STREAM input);
  static pANTLR3_COMMON_TREE_NODE_STREAM	
  					getTreeNodeStream	    (pANTLR3_TREE_PARSER parser);
  static void			freeParser				(pANTLR3_TREE_PARSER parser);    
  static void *		getCurrentInputSymbol	(pANTLR3_BASE_RECOGNIZER recognizer, pANTLR3_INT_STREAM istream);
  static void *		getMissingSymbol		(pANTLR3_BASE_RECOGNIZER recognizer, pANTLR3_INT_STREAM	istream, pANTLR3_EXCEPTION	e,
  												ANTLR3_UINT32 expectedTokenType, pANTLR3_BITSET_LIST follow);
  
  
  ANTLR3_API pANTLR3_TREE_PARSER
  antlr3TreeParserNewStream(ANTLR3_UINT32 sizeHint, pANTLR3_COMMON_TREE_NODE_STREAM ctnstream, pANTLR3_RECOGNIZER_SHARED_STATE state)
  {
  	pANTLR3_TREE_PARSER	    parser;
  
  	/** Allocate tree parser memory
  	*/
  	parser  =(pANTLR3_TREE_PARSER) ANTLR3_MALLOC(sizeof(ANTLR3_TREE_PARSER));
  
  	if	(parser == NULL)
  	{
  		return	NULL;
  	}
  
  	/* Create and install a base recognizer which does most of the work for us
  	*/
  	parser->rec =  antlr3BaseRecognizerNew(ANTLR3_TYPE_PARSER, sizeHint, state);
  
  	if	(parser->rec == NULL)
  	{
  		parser->free(parser);
  		return	NULL;
  	}
  
  	/* Ensure we can track back to the tree parser super structure
  	* from the base recognizer structure
  	*/
  	parser->rec->super	= parser;
  	parser->rec->type	= ANTLR3_TYPE_TREE_PARSER;
  
  	/* Install our base recognizer overrides
  	*/
  	parser->rec->mismatch				= mismatch;
  	parser->rec->exConstruct			= antlr3MTNExceptionNew;
  	parser->rec->getCurrentInputSymbol	= getCurrentInputSymbol;
  	parser->rec->getMissingSymbol		= getMissingSymbol;
  
  	/* Install tree parser API
  	*/
  	parser->getTreeNodeStream	=  getTreeNodeStream;
  	parser->setTreeNodeStream	=  setTreeNodeStream;
  	parser->free		=  freeParser;
  
  	/* Install the tree node stream
  	*/
  	parser->setTreeNodeStream(parser, ctnstream);
  
  	return  parser;
  }
  
  /**
   * \brief
   * Creates a new Mismatched Tree Nde Exception and inserts in the recognizer
   * exception stack.
   * 
   * \param recognizer
   * Context pointer for this recognizer
   * 
   */
  ANTLR3_API	void
  antlr3MTNExceptionNew(pANTLR3_BASE_RECOGNIZER recognizer)
  {
      /* Create a basic recognition exception structure
       */
      antlr3RecognitionExceptionNew(recognizer);
  
      /* Now update it to indicate this is a Mismatched token exception
       */
      recognizer->state->exception->name		= ANTLR3_MISMATCHED_TREE_NODE_NAME;
      recognizer->state->exception->type		= ANTLR3_MISMATCHED_TREE_NODE_EXCEPTION;
  
      return;
  }
  
  
  static void
  freeParser	(pANTLR3_TREE_PARSER parser)
  {
  	if	(parser->rec != NULL)
  	{
  		// This may have ben a delegate or delegator parser, in which case the
  		// state may already have been freed (and set to NULL therefore)
  		// so we ignore the state if we don't have it.
  		//
  		if	(parser->rec->state != NULL)
  		{
  			if	(parser->rec->state->following != NULL)
  			{
  				parser->rec->state->following->free(parser->rec->state->following);
  				parser->rec->state->following = NULL;
  			}
  		}
  	    parser->rec->free(parser->rec);
  	    parser->rec	= NULL;
      }
  
      ANTLR3_FREE(parser);
  }
  
  /** Set the input stream and reset the parser
   */
  static void
  setTreeNodeStream	(pANTLR3_TREE_PARSER parser, pANTLR3_COMMON_TREE_NODE_STREAM input)
  {
      parser->ctnstream = input;
      parser->rec->reset		(parser->rec);
      parser->ctnstream->reset	(parser->ctnstream);
  }
  
  /** Return a pointer to the input stream
   */
  static pANTLR3_COMMON_TREE_NODE_STREAM
  getTreeNodeStream	(pANTLR3_TREE_PARSER parser)
  {
      return  parser->ctnstream;
  }
  
  
  /** Override for standard base recognizer mismatch function
   *  as we have DOWN/UP nodes in the stream that have no line info,
   *  plus we want to alter the exception type.
   */
  static void
  mismatch	    (pANTLR3_BASE_RECOGNIZER recognizer, ANTLR3_UINT32 ttype, pANTLR3_BITSET_LIST follow)
  {
      recognizer->exConstruct(recognizer);
      recognizer->recoverFromMismatchedToken(recognizer, ttype, follow);
  }
  
  #ifdef ANTLR3_WINDOWS
  #pragma warning	(push)
  #pragma warning (disable : 4100)
  #endif
  
  // Default implementation is for parser and assumes a token stream as supplied by the runtime.
  // You MAY need override this function if the standard TOKEN_STREAM is not what you are using.
  //
  static void *				
  getCurrentInputSymbol		(pANTLR3_BASE_RECOGNIZER recognizer, pANTLR3_INT_STREAM istream)
  {
  	pANTLR3_TREE_NODE_STREAM		tns;
      pANTLR3_COMMON_TREE_NODE_STREAM	ctns;
  
      tns	    = (pANTLR3_TREE_NODE_STREAM)(istream->super);
      ctns    = tns->ctns;
  	return tns->_LT(tns, 1);
  }
  
  
  // Default implementation is for parser and assumes a token stream as supplied by the runtime.
  // You MAY need override this function if the standard BASE_TREE is not what you are using.
  //
  static void *				
  getMissingSymbol			(pANTLR3_BASE_RECOGNIZER recognizer, pANTLR3_INT_STREAM	istream, pANTLR3_EXCEPTION	e,
  									ANTLR3_UINT32 expectedTokenType, pANTLR3_BITSET_LIST follow)
  {
  	pANTLR3_TREE_NODE_STREAM		tns;
      pANTLR3_COMMON_TREE_NODE_STREAM	ctns;
  	pANTLR3_BASE_TREE				node;
  	pANTLR3_BASE_TREE				current;
  	pANTLR3_COMMON_TOKEN			token;
  	pANTLR3_STRING					text;
      ANTLR3_INT32                   i;
  
  	// Dereference the standard pointers
  	//
      tns	    = (pANTLR3_TREE_NODE_STREAM)(istream->super);
      ctns    = tns->ctns;
      
  	// Create a new empty node, by stealing the current one, or the previous one if the current one is EOF
  	//
  	current	= tns->_LT(tns, 1);
      i       = -1;
  
  	if	(current == &ctns->EOF_NODE.baseTree)
  	{
  		current = tns->_LT(tns, -1);
          i--;
  	}
      while (((pANTLR3_COMMON_TREE)(current->super))->factory == NULL)
  	{
  		current = tns->_LT(tns, i--);
      }
  
  	node	= current->dupNode(current);
  
  	// Find the newly dupicated token
  	//
  	token	= node->getToken(node);
  
  	// Create the token text that shows it has been inserted
  	//
  	token->setText8			(token, (pANTLR3_UINT8)"<missing ");
  	text = token->getText	(token);
  	text->append8			(text, (const char *)recognizer->state->tokenNames[expectedTokenType]);
  	text->append8			(text, (const char *)">");
  	
  	// Finally return the pointer to our new node
  	//
  	return	node;
  }
  #ifdef ANTLR3_WINDOWS
  #pragma warning	(pop)
  #endif
  
  