2 * Implementation of the tree parser and overrides for the base recognizer
6 // Copyright (c) 2005-2009 Jim Idle, Temporal Wave LLC
7 // http://www.temporal-wave.com
8 // http://www.linkedin.com/in/jimidle
10 // All rights reserved.
12 // Redistribution and use in source and binary forms, with or without
13 // modification, are permitted provided that the following conditions
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.
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.
34 #include <antlr3treeparser.h>
36 /* BASE Recognizer overrides
38 static void mismatch (pANTLR3_BASE_RECOGNIZER recognizer
, ANTLR3_UINT32 ttype
, pANTLR3_BITSET_LIST follow
);
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
);
51 ANTLR3_API pANTLR3_TREE_PARSER
52 antlr3TreeParserNewStream(ANTLR3_UINT32 sizeHint
, pANTLR3_COMMON_TREE_NODE_STREAM ctnstream
, pANTLR3_RECOGNIZER_SHARED_STATE state
)
54 pANTLR3_TREE_PARSER parser
;
56 /** Allocate tree parser memory
58 parser
=(pANTLR3_TREE_PARSER
) ANTLR3_MALLOC(sizeof(ANTLR3_TREE_PARSER
));
65 /* Create and install a base recognizer which does most of the work for us
67 parser
->rec
= antlr3BaseRecognizerNew(ANTLR3_TYPE_PARSER
, sizeHint
, state
);
69 if (parser
->rec
== NULL
)
75 /* Ensure we can track back to the tree parser super structure
76 * from the base recognizer structure
78 parser
->rec
->super
= parser
;
79 parser
->rec
->type
= ANTLR3_TYPE_TREE_PARSER
;
81 /* Install our base recognizer overrides
83 parser
->rec
->mismatch
= mismatch
;
84 parser
->rec
->exConstruct
= antlr3MTNExceptionNew
;
85 parser
->rec
->getCurrentInputSymbol
= getCurrentInputSymbol
;
86 parser
->rec
->getMissingSymbol
= getMissingSymbol
;
88 /* Install tree parser API
90 parser
->getTreeNodeStream
= getTreeNodeStream
;
91 parser
->setTreeNodeStream
= setTreeNodeStream
;
92 parser
->free
= freeParser
;
94 /* Install the tree node stream
96 parser
->setTreeNodeStream(parser
, ctnstream
);
103 * Creates a new Mismatched Tree Nde Exception and inserts in the recognizer
107 * Context pointer for this recognizer
111 antlr3MTNExceptionNew(pANTLR3_BASE_RECOGNIZER recognizer
)
113 /* Create a basic recognition exception structure
115 antlr3RecognitionExceptionNew(recognizer
);
117 /* Now update it to indicate this is a Mismatched token exception
119 recognizer
->state
->exception
->name
= ANTLR3_MISMATCHED_TREE_NODE_NAME
;
120 recognizer
->state
->exception
->type
= ANTLR3_MISMATCHED_TREE_NODE_EXCEPTION
;
127 freeParser (pANTLR3_TREE_PARSER parser
)
129 if (parser
->rec
!= NULL
)
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.
135 if (parser
->rec
->state
!= NULL
)
137 if (parser
->rec
->state
->following
!= NULL
)
139 stackFree(parser
->rec
->state
->following
);
140 parser
->rec
->state
->following
= NULL
;
143 parser
->rec
->free(parser
->rec
);
150 /** Set the input stream and reset the parser
153 setTreeNodeStream (pANTLR3_TREE_PARSER parser
, pANTLR3_COMMON_TREE_NODE_STREAM input
)
155 parser
->ctnstream
= input
;
156 parser
->rec
->reset (parser
->rec
);
157 parser
->ctnstream
->reset (parser
->ctnstream
);
160 /** Return a pointer to the input stream
162 static pANTLR3_COMMON_TREE_NODE_STREAM
163 getTreeNodeStream (pANTLR3_TREE_PARSER parser
)
165 return parser
->ctnstream
;
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.
174 mismatch (pANTLR3_BASE_RECOGNIZER recognizer
, ANTLR3_UINT32 ttype
, pANTLR3_BITSET_LIST follow
)
176 recognizer
->exConstruct(recognizer
);
177 recognizer
->recoverFromMismatchedToken(recognizer
, ttype
, follow
);
180 #ifdef ANTLR3_WINDOWS
181 #pragma warning (push)
182 #pragma warning (disable : 4100)
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.
189 getCurrentInputSymbol (pANTLR3_BASE_RECOGNIZER recognizer
, pANTLR3_INT_STREAM istream
)
191 pANTLR3_TREE_NODE_STREAM tns
= (pANTLR3_TREE_NODE_STREAM
)(istream
->super
);
192 return tns
->_LT(tns
, 1);
196 // Default implementation is for parser and assumes a token stream as supplied by the runtime.
197 // You MAY need override this function if the standard BASE_TREE is not what you are using.
200 getMissingSymbol (pANTLR3_BASE_RECOGNIZER recognizer
, pANTLR3_INT_STREAM istream
, pANTLR3_EXCEPTION e
,
201 ANTLR3_UINT32 expectedTokenType
, pANTLR3_BITSET_LIST follow
)
203 pANTLR3_TREE_NODE_STREAM tns
;
204 pANTLR3_COMMON_TREE_NODE_STREAM ctns
;
205 pANTLR3_BASE_TREE node
;
206 pANTLR3_BASE_TREE current
;
207 pANTLR3_COMMON_TOKEN token
;
211 // Dereference the standard pointers
213 tns
= (pANTLR3_TREE_NODE_STREAM
)(istream
->super
);
216 // Create a new empty node, by stealing the current one, or the previous one if the current one is EOF
218 current
= tns
->_LT(tns
, 1);
221 if (current
== &ctns
->EOF_NODE
.baseTree
)
223 current
= tns
->_LT(tns
, -1);
226 while (((pANTLR3_COMMON_TREE
)(current
->super
))->factory
== NULL
)
228 current
= tns
->_LT(tns
, i
--);
231 node
= current
->dupNode(current
);
233 // Find the newly dupicated token
235 token
= node
->getToken(node
);
237 // Create the token text that shows it has been inserted
239 token
->setText8 (token
, (pANTLR3_UINT8
)"<missing ");
240 text
= token
->getText (token
);
241 text
->append8 (text
, (const char *)recognizer
->state
->tokenNames
[expectedTokenType
]);
242 text
->append8 (text
, (const char *)">");
244 // Finally return the pointer to our new node
248 #ifdef ANTLR3_WINDOWS
249 #pragma warning (pop)