/** \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

