2 * Implementation of the tree parser and overrides for the base recognizer
\r
5 // [The "BSD licence"]
\r
6 // Copyright (c) 2005-2009 Jim Idle, Temporal Wave LLC
\r
7 // http://www.temporal-wave.com
\r
8 // http://www.linkedin.com/in/jimidle
\r
10 // All rights reserved.
\r
12 // Redistribution and use in source and binary forms, with or without
\r
13 // modification, are permitted provided that the following conditions
\r
15 // 1. Redistributions of source code must retain the above copyright
\r
16 // notice, this list of conditions and the following disclaimer.
\r
17 // 2. Redistributions in binary form must reproduce the above copyright
\r
18 // notice, this list of conditions and the following disclaimer in the
\r
19 // documentation and/or other materials provided with the distribution.
\r
20 // 3. The name of the author may not be used to endorse or promote products
\r
21 // derived from this software without specific prior written permission.
\r
23 // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
\r
24 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
\r
25 // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
\r
26 // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
\r
27 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
\r
28 // NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
\r
29 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
\r
30 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
\r
31 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
\r
32 // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\r
34 #include <antlr3treeparser.h>
\r
36 /* BASE Recognizer overrides
\r
38 static void mismatch (pANTLR3_BASE_RECOGNIZER recognizer, ANTLR3_UINT32 ttype, pANTLR3_BITSET_LIST follow);
\r
42 static void setTreeNodeStream (pANTLR3_TREE_PARSER parser, pANTLR3_COMMON_TREE_NODE_STREAM input);
\r
43 static pANTLR3_COMMON_TREE_NODE_STREAM
\r
44 getTreeNodeStream (pANTLR3_TREE_PARSER parser);
\r
45 static void freeParser (pANTLR3_TREE_PARSER parser);
\r
46 static void * getCurrentInputSymbol (pANTLR3_BASE_RECOGNIZER recognizer, pANTLR3_INT_STREAM istream);
\r
47 static void * getMissingSymbol (pANTLR3_BASE_RECOGNIZER recognizer, pANTLR3_INT_STREAM istream, pANTLR3_EXCEPTION e,
\r
48 ANTLR3_UINT32 expectedTokenType, pANTLR3_BITSET_LIST follow);
\r
51 ANTLR3_API pANTLR3_TREE_PARSER
\r
52 antlr3TreeParserNewStream(ANTLR3_UINT32 sizeHint, pANTLR3_COMMON_TREE_NODE_STREAM ctnstream, pANTLR3_RECOGNIZER_SHARED_STATE state)
\r
54 pANTLR3_TREE_PARSER parser;
\r
56 /** Allocate tree parser memory
\r
58 parser =(pANTLR3_TREE_PARSER) ANTLR3_MALLOC(sizeof(ANTLR3_TREE_PARSER));
\r
65 /* Create and install a base recognizer which does most of the work for us
\r
67 parser->rec = antlr3BaseRecognizerNew(ANTLR3_TYPE_PARSER, sizeHint, state);
\r
69 if (parser->rec == NULL)
\r
71 parser->free(parser);
\r
75 /* Ensure we can track back to the tree parser super structure
\r
76 * from the base recognizer structure
\r
78 parser->rec->super = parser;
\r
79 parser->rec->type = ANTLR3_TYPE_TREE_PARSER;
\r
81 /* Install our base recognizer overrides
\r
83 parser->rec->mismatch = mismatch;
\r
84 parser->rec->exConstruct = antlr3MTNExceptionNew;
\r
85 parser->rec->getCurrentInputSymbol = getCurrentInputSymbol;
\r
86 parser->rec->getMissingSymbol = getMissingSymbol;
\r
88 /* Install tree parser API
\r
90 parser->getTreeNodeStream = getTreeNodeStream;
\r
91 parser->setTreeNodeStream = setTreeNodeStream;
\r
92 parser->free = freeParser;
\r
94 /* Install the tree node stream
\r
96 parser->setTreeNodeStream(parser, ctnstream);
\r
103 * Creates a new Mismatched Tree Nde Exception and inserts in the recognizer
\r
106 * \param recognizer
\r
107 * Context pointer for this recognizer
\r
111 antlr3MTNExceptionNew(pANTLR3_BASE_RECOGNIZER recognizer)
\r
113 /* Create a basic recognition exception structure
\r
115 antlr3RecognitionExceptionNew(recognizer);
\r
117 /* Now update it to indicate this is a Mismatched token exception
\r
119 recognizer->state->exception->name = ANTLR3_MISMATCHED_TREE_NODE_NAME;
\r
120 recognizer->state->exception->type = ANTLR3_MISMATCHED_TREE_NODE_EXCEPTION;
\r
127 freeParser (pANTLR3_TREE_PARSER parser)
\r
129 if (parser->rec != NULL)
\r
131 // This may have ben a delegate or delegator parser, in which case the
\r
132 // state may already have been freed (and set to NULL therefore)
\r
133 // so we ignore the state if we don't have it.
\r
135 if (parser->rec->state != NULL)
\r
137 if (parser->rec->state->following != NULL)
\r
139 parser->rec->state->following->free(parser->rec->state->following);
\r
140 parser->rec->state->following = NULL;
\r
143 parser->rec->free(parser->rec);
\r
144 parser->rec = NULL;
\r
147 ANTLR3_FREE(parser);
\r
150 /** Set the input stream and reset the parser
\r
153 setTreeNodeStream (pANTLR3_TREE_PARSER parser, pANTLR3_COMMON_TREE_NODE_STREAM input)
\r
155 parser->ctnstream = input;
\r
156 parser->rec->reset (parser->rec);
\r
157 parser->ctnstream->reset (parser->ctnstream);
\r
160 /** Return a pointer to the input stream
\r
162 static pANTLR3_COMMON_TREE_NODE_STREAM
\r
163 getTreeNodeStream (pANTLR3_TREE_PARSER parser)
\r
165 return parser->ctnstream;
\r
169 /** Override for standard base recognizer mismatch function
\r
170 * as we have DOWN/UP nodes in the stream that have no line info,
\r
171 * plus we want to alter the exception type.
\r
174 mismatch (pANTLR3_BASE_RECOGNIZER recognizer, ANTLR3_UINT32 ttype, pANTLR3_BITSET_LIST follow)
\r
176 recognizer->exConstruct(recognizer);
\r
177 recognizer->recoverFromMismatchedToken(recognizer, ttype, follow);
\r
180 #ifdef ANTLR3_WINDOWS
\r
181 #pragma warning (push)
\r
182 #pragma warning (disable : 4100)
\r
185 // Default implementation is for parser and assumes a token stream as supplied by the runtime.
\r
186 // You MAY need override this function if the standard TOKEN_STREAM is not what you are using.
\r
189 getCurrentInputSymbol (pANTLR3_BASE_RECOGNIZER recognizer, pANTLR3_INT_STREAM istream)
\r
191 pANTLR3_TREE_NODE_STREAM tns;
\r
192 pANTLR3_COMMON_TREE_NODE_STREAM ctns;
\r
194 tns = (pANTLR3_TREE_NODE_STREAM)(istream->super);
\r
196 return tns->_LT(tns, 1);
\r
200 // Default implementation is for parser and assumes a token stream as supplied by the runtime.
\r
201 // You MAY need override this function if the standard BASE_TREE is not what you are using.
\r
204 getMissingSymbol (pANTLR3_BASE_RECOGNIZER recognizer, pANTLR3_INT_STREAM istream, pANTLR3_EXCEPTION e,
\r
205 ANTLR3_UINT32 expectedTokenType, pANTLR3_BITSET_LIST follow)
\r
207 pANTLR3_TREE_NODE_STREAM tns;
\r
208 pANTLR3_COMMON_TREE_NODE_STREAM ctns;
\r
209 pANTLR3_BASE_TREE node;
\r
210 pANTLR3_BASE_TREE current;
\r
211 pANTLR3_COMMON_TOKEN token;
\r
212 pANTLR3_STRING text;
\r
215 // Dereference the standard pointers
\r
217 tns = (pANTLR3_TREE_NODE_STREAM)(istream->super);
\r
220 // Create a new empty node, by stealing the current one, or the previous one if the current one is EOF
\r
222 current = tns->_LT(tns, 1);
\r
225 if (current == &ctns->EOF_NODE.baseTree)
\r
227 current = tns->_LT(tns, -1);
\r
230 while (((pANTLR3_COMMON_TREE)(current->super))->factory == NULL)
\r
232 current = tns->_LT(tns, i--);
\r
235 node = current->dupNode(current);
\r
237 // Find the newly dupicated token
\r
239 token = node->getToken(node);
\r
241 // Create the token text that shows it has been inserted
\r
243 token->setText8 (token, (pANTLR3_UINT8)"<missing ");
\r
244 text = token->getText (token);
\r
245 text->append8 (text, (const char *)recognizer->state->tokenNames[expectedTokenType]);
\r
246 text->append8 (text, (const char *)">");
\r
248 // Finally return the pointer to our new node
\r
252 #ifdef ANTLR3_WINDOWS
\r
253 #pragma warning (pop)
\r