Home | History | Annotate | Download | only in src
      1 /** \file
      2  *  Implementation of the tree parser and overrides for the base recognizer
      3  */
      4 
      5 // [The "BSD licence"]
      6 // Copyright (c) 2005-2009 Jim Idle, Temporal Wave LLC
      7 // http://www.temporal-wave.com
      8 // http://www.linkedin.com/in/jimidle
      9 //
     10 // All rights reserved.
     11 //
     12 // Redistribution and use in source and binary forms, with or without
     13 // modification, are permitted provided that the following conditions
     14 // are met:
     15 // 1. Redistributions of source code must retain the above copyright
     16 //    notice, this list of conditions and the following disclaimer.
     17 // 2. Redistributions in binary form must reproduce the above copyright
     18 //    notice, this list of conditions and the following disclaimer in the
     19 //    documentation and/or other materials provided with the distribution.
     20 // 3. The name of the author may not be used to endorse or promote products
     21 //    derived from this software without specific prior written permission.
     22 //
     23 // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     24 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     25 // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     26 // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     27 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     28 // NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     29 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     30 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     31 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     32 // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     33 
     34 #include    <antlr3treeparser.h>
     35 
     36 /* BASE Recognizer overrides
     37  */
     38 static void				mismatch	    (pANTLR3_BASE_RECOGNIZER recognizer, ANTLR3_UINT32 ttype, pANTLR3_BITSET_LIST follow);
     39 
     40 /* Tree parser API
     41  */
     42 static void			setTreeNodeStream	    (pANTLR3_TREE_PARSER parser, pANTLR3_COMMON_TREE_NODE_STREAM input);
     43 static pANTLR3_COMMON_TREE_NODE_STREAM
     44 					getTreeNodeStream	    (pANTLR3_TREE_PARSER parser);
     45 static void			freeParser				(pANTLR3_TREE_PARSER parser);
     46 static void *		getCurrentInputSymbol	(pANTLR3_BASE_RECOGNIZER recognizer, pANTLR3_INT_STREAM istream);
     47 static void *		getMissingSymbol		(pANTLR3_BASE_RECOGNIZER recognizer, pANTLR3_INT_STREAM	istream, pANTLR3_EXCEPTION	e,
     48 												ANTLR3_UINT32 expectedTokenType, pANTLR3_BITSET_LIST follow);
     49 
     50 
     51 ANTLR3_API pANTLR3_TREE_PARSER
     52 antlr3TreeParserNewStream(ANTLR3_UINT32 sizeHint, pANTLR3_COMMON_TREE_NODE_STREAM ctnstream, pANTLR3_RECOGNIZER_SHARED_STATE state)
     53 {
     54 	pANTLR3_TREE_PARSER	    parser;
     55 
     56 	/** Allocate tree parser memory
     57 	*/
     58 	parser  =(pANTLR3_TREE_PARSER) ANTLR3_MALLOC(sizeof(ANTLR3_TREE_PARSER));
     59 
     60 	if	(parser == NULL)
     61 	{
     62 		return	NULL;
     63 	}
     64 
     65 	/* Create and install a base recognizer which does most of the work for us
     66 	*/
     67 	parser->rec =  antlr3BaseRecognizerNew(ANTLR3_TYPE_PARSER, sizeHint, state);
     68 
     69 	if	(parser->rec == NULL)
     70 	{
     71 		parser->free(parser);
     72 		return	NULL;
     73 	}
     74 
     75 	/* Ensure we can track back to the tree parser super structure
     76 	* from the base recognizer structure
     77 	*/
     78 	parser->rec->super	= parser;
     79 	parser->rec->type	= ANTLR3_TYPE_TREE_PARSER;
     80 
     81 	/* Install our base recognizer overrides
     82 	*/
     83 	parser->rec->mismatch				= mismatch;
     84 	parser->rec->exConstruct			= antlr3MTNExceptionNew;
     85 	parser->rec->getCurrentInputSymbol	= getCurrentInputSymbol;
     86 	parser->rec->getMissingSymbol		= getMissingSymbol;
     87 
     88 	/* Install tree parser API
     89 	*/
     90 	parser->getTreeNodeStream	=  getTreeNodeStream;
     91 	parser->setTreeNodeStream	=  setTreeNodeStream;
     92 	parser->free		=  freeParser;
     93 
     94 	/* Install the tree node stream
     95 	*/
     96 	parser->setTreeNodeStream(parser, ctnstream);
     97 
     98 	return  parser;
     99 }
    100 
    101 /**
    102  * \brief
    103  * Creates a new Mismatched Tree Nde Exception and inserts in the recognizer
    104  * exception stack.
    105  *
    106  * \param recognizer
    107  * Context pointer for this recognizer
    108  *
    109  */
    110 ANTLR3_API	void
    111 antlr3MTNExceptionNew(pANTLR3_BASE_RECOGNIZER recognizer)
    112 {
    113     /* Create a basic recognition exception structure
    114      */
    115     antlr3RecognitionExceptionNew(recognizer);
    116 
    117     /* Now update it to indicate this is a Mismatched token exception
    118      */
    119     recognizer->state->exception->name		= ANTLR3_MISMATCHED_TREE_NODE_NAME;
    120     recognizer->state->exception->type		= ANTLR3_MISMATCHED_TREE_NODE_EXCEPTION;
    121 
    122     return;
    123 }
    124 
    125 
    126 static void
    127 freeParser	(pANTLR3_TREE_PARSER parser)
    128 {
    129 	if	(parser->rec != NULL)
    130 	{
    131 		// This may have ben a delegate or delegator parser, in which case the
    132 		// state may already have been freed (and set to NULL therefore)
    133 		// so we ignore the state if we don't have it.
    134 		//
    135 		if	(parser->rec->state != NULL)
    136 		{
    137 			if	(parser->rec->state->following != NULL)
    138 			{
    139 				parser->rec->state->following->free(parser->rec->state->following);
    140 				parser->rec->state->following = NULL;
    141 			}
    142 		}
    143 	    parser->rec->free(parser->rec);
    144 	    parser->rec	= NULL;
    145     }
    146 
    147     ANTLR3_FREE(parser);
    148 }
    149 
    150 /** Set the input stream and reset the parser
    151  */
    152 static void
    153 setTreeNodeStream	(pANTLR3_TREE_PARSER parser, pANTLR3_COMMON_TREE_NODE_STREAM input)
    154 {
    155     parser->ctnstream = input;
    156     parser->rec->reset		(parser->rec);
    157     parser->ctnstream->reset	(parser->ctnstream);
    158 }
    159 
    160 /** Return a pointer to the input stream
    161  */
    162 static pANTLR3_COMMON_TREE_NODE_STREAM
    163 getTreeNodeStream	(pANTLR3_TREE_PARSER parser)
    164 {
    165     return  parser->ctnstream;
    166 }
    167 
    168 
    169 /** Override for standard base recognizer mismatch function
    170  *  as we have DOWN/UP nodes in the stream that have no line info,
    171  *  plus we want to alter the exception type.
    172  */
    173 static void
    174 mismatch	    (pANTLR3_BASE_RECOGNIZER recognizer, ANTLR3_UINT32 ttype, pANTLR3_BITSET_LIST follow)
    175 {
    176     recognizer->exConstruct(recognizer);
    177     recognizer->recoverFromMismatchedToken(recognizer, ttype, follow);
    178 }
    179 
    180 #ifdef ANTLR3_WINDOWS
    181 #pragma warning	(push)
    182 #pragma warning (disable : 4100)
    183 #endif
    184 
    185 // Default implementation is for parser and assumes a token stream as supplied by the runtime.
    186 // You MAY need override this function if the standard TOKEN_STREAM is not what you are using.
    187 //
    188 static void *
    189 getCurrentInputSymbol		(pANTLR3_BASE_RECOGNIZER recognizer, pANTLR3_INT_STREAM istream)
    190 {
    191 	pANTLR3_TREE_NODE_STREAM		tns;
    192     pANTLR3_COMMON_TREE_NODE_STREAM	ctns;
    193 
    194     tns	    = (pANTLR3_TREE_NODE_STREAM)(istream->super);
    195     ctns    = tns->ctns;
    196 	return tns->_LT(tns, 1);
    197 }
    198 
    199 
    200 // Default implementation is for parser and assumes a token stream as supplied by the runtime.
    201 // You MAY need override this function if the standard BASE_TREE is not what you are using.
    202 //
    203 static void *
    204 getMissingSymbol			(pANTLR3_BASE_RECOGNIZER recognizer, pANTLR3_INT_STREAM	istream, pANTLR3_EXCEPTION	e,
    205 									ANTLR3_UINT32 expectedTokenType, pANTLR3_BITSET_LIST follow)
    206 {
    207 	pANTLR3_TREE_NODE_STREAM		tns;
    208     pANTLR3_COMMON_TREE_NODE_STREAM	ctns;
    209 	pANTLR3_BASE_TREE				node;
    210 	pANTLR3_BASE_TREE				current;
    211 	pANTLR3_COMMON_TOKEN			token;
    212 	pANTLR3_STRING					text;
    213     ANTLR3_INT32                   i;
    214 
    215 	// Dereference the standard pointers
    216 	//
    217     tns	    = (pANTLR3_TREE_NODE_STREAM)(istream->super);
    218     ctns    = tns->ctns;
    219 
    220 	// Create a new empty node, by stealing the current one, or the previous one if the current one is EOF
    221 	//
    222 	current	= tns->_LT(tns, 1);
    223     i       = -1;
    224 
    225 	if	(current == &ctns->EOF_NODE.baseTree)
    226 	{
    227 		current = tns->_LT(tns, -1);
    228         i--;
    229 	}
    230     while (((pANTLR3_COMMON_TREE)(current->super))->factory == NULL)
    231 	{
    232 		current = tns->_LT(tns, i--);
    233     }
    234 
    235 	node	= current->dupNode(current);
    236 
    237 	// Find the newly dupicated token
    238 	//
    239 	token	= node->getToken(node);
    240 
    241 	// Create the token text that shows it has been inserted
    242 	//
    243 	token->setText8			(token, (pANTLR3_UINT8)"<missing ");
    244 	text = token->getText	(token);
    245 	text->append8			(text, (const char *)recognizer->state->tokenNames[expectedTokenType]);
    246 	text->append8			(text, (const char *)">");
    247 
    248 	// Finally return the pointer to our new node
    249 	//
    250 	return	node;
    251 }
    252 #ifdef ANTLR3_WINDOWS
    253 #pragma warning	(pop)
    254 #endif
    255 
    256