diff options
Diffstat (limited to 'antlr/libantlr3c-3.4/src/antlr3treeparser.c')
-rw-r--r-- | antlr/libantlr3c-3.4/src/antlr3treeparser.c | 255 |
1 files changed, 255 insertions, 0 deletions
diff --git a/antlr/libantlr3c-3.4/src/antlr3treeparser.c b/antlr/libantlr3c-3.4/src/antlr3treeparser.c new file mode 100644 index 0000000..b7e035a --- /dev/null +++ b/antlr/libantlr3c-3.4/src/antlr3treeparser.c @@ -0,0 +1,255 @@ +/** \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 + |