aboutsummaryrefslogtreecommitdiff
path: root/runtime/C/src/antlr3treeparser.c
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/C/src/antlr3treeparser.c')
-rw-r--r--runtime/C/src/antlr3treeparser.c255
1 files changed, 255 insertions, 0 deletions
diff --git a/runtime/C/src/antlr3treeparser.c b/runtime/C/src/antlr3treeparser.c
new file mode 100644
index 0000000..b7e035a
--- /dev/null
+++ b/runtime/C/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
+