2 * This is the standard tree adaptor used by the C runtime unless the grammar
3 * source file says to use anything different. It embeds a BASE_TREE to which
4 * it adds its own implementation of anything that the base tree is not
5 * good for, plus a number of methods that any other adaptor type
6 * needs to implement too.
7 * \ingroup pANTLR3_COMMON_TREE_ADAPTOR
10 // [The "BSD licence"]
11 // Copyright (c) 2005-2009 Jim Idle, Temporal Wave LLC
12 // http://www.temporal-wave.com
13 // http://www.linkedin.com/in/jimidle
15 // All rights reserved.
17 // Redistribution and use in source and binary forms, with or without
18 // modification, are permitted provided that the following conditions
20 // 1. Redistributions of source code must retain the above copyright
21 // notice, this list of conditions and the following disclaimer.
22 // 2. Redistributions in binary form must reproduce the above copyright
23 // notice, this list of conditions and the following disclaimer in the
24 // documentation and/or other materials provided with the distribution.
25 // 3. The name of the author may not be used to endorse or promote products
26 // derived from this software without specific prior written permission.
28 // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
29 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
30 // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
31 // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
32 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
33 // NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
34 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
35 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
36 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
37 // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 #include <antlr3commontreeadaptor.h>
42 #pragma warning( disable : 4100 )
45 /* BASE_TREE_ADAPTOR overrides... */
46 static pANTLR3_BASE_TREE
dupNode (pANTLR3_BASE_TREE_ADAPTOR adaptor
, pANTLR3_BASE_TREE treeNode
);
47 static pANTLR3_BASE_TREE
create (pANTLR3_BASE_TREE_ADAPTOR adpator
, pANTLR3_COMMON_TOKEN payload
);
48 static pANTLR3_BASE_TREE
dbgCreate (pANTLR3_BASE_TREE_ADAPTOR adaptor
, pANTLR3_COMMON_TOKEN payload
);
49 static pANTLR3_COMMON_TOKEN
createToken (pANTLR3_BASE_TREE_ADAPTOR adaptor
, ANTLR3_UINT32 tokenType
, pANTLR3_UINT8 text
);
50 static pANTLR3_COMMON_TOKEN
createTokenFromToken (pANTLR3_BASE_TREE_ADAPTOR adaptor
, pANTLR3_COMMON_TOKEN fromToken
);
51 static pANTLR3_STRING
getText (pANTLR3_BASE_TREE_ADAPTOR adaptor
, pANTLR3_BASE_TREE t
);
52 static ANTLR3_UINT32
getType (pANTLR3_BASE_TREE_ADAPTOR adaptor
, pANTLR3_BASE_TREE t
);
53 static pANTLR3_BASE_TREE
getChild (pANTLR3_BASE_TREE_ADAPTOR adaptor
, pANTLR3_BASE_TREE t
, ANTLR3_UINT32 i
);
54 static ANTLR3_UINT32
getChildCount (pANTLR3_BASE_TREE_ADAPTOR adaptor
, pANTLR3_BASE_TREE t
);
55 static void replaceChildren (pANTLR3_BASE_TREE_ADAPTOR adaptor
, pANTLR3_BASE_TREE parent
, ANTLR3_INT32 startChildIndex
, ANTLR3_INT32 stopChildIndex
, pANTLR3_BASE_TREE t
);
56 static void setDebugEventListener (pANTLR3_BASE_TREE_ADAPTOR adaptor
, pANTLR3_DEBUG_EVENT_LISTENER debugger
);
57 static void setChildIndex (pANTLR3_BASE_TREE_ADAPTOR adaptor
, pANTLR3_BASE_TREE t
, ANTLR3_INT32 i
);
58 static ANTLR3_INT32
getChildIndex (pANTLR3_BASE_TREE_ADAPTOR adaptor
, pANTLR3_BASE_TREE t
);
59 static void setParent (pANTLR3_BASE_TREE_ADAPTOR adaptor
, pANTLR3_BASE_TREE child
, pANTLR3_BASE_TREE parent
);
60 static pANTLR3_BASE_TREE
getParent (pANTLR3_BASE_TREE_ADAPTOR adaptor
, pANTLR3_BASE_TREE child
);
61 static void setChild (pANTLR3_BASE_TREE_ADAPTOR adaptor
, pANTLR3_BASE_TREE t
, ANTLR3_UINT32 i
, pANTLR3_BASE_TREE child
);
62 static void deleteChild (pANTLR3_BASE_TREE_ADAPTOR adaptor
, pANTLR3_BASE_TREE t
, ANTLR3_UINT32 i
);
63 static pANTLR3_BASE_TREE
errorNode (pANTLR3_BASE_TREE_ADAPTOR adaptor
, pANTLR3_TOKEN_STREAM ctnstream
, pANTLR3_COMMON_TOKEN startToken
, pANTLR3_COMMON_TOKEN stopToken
, pANTLR3_EXCEPTION e
);
64 /* Methods specific to each tree adaptor
66 static void setTokenBoundaries (pANTLR3_BASE_TREE_ADAPTOR adaptor
, pANTLR3_BASE_TREE t
, pANTLR3_COMMON_TOKEN startToken
, pANTLR3_COMMON_TOKEN stopToken
);
67 static void dbgSetTokenBoundaries (pANTLR3_BASE_TREE_ADAPTOR adaptor
, pANTLR3_BASE_TREE t
, pANTLR3_COMMON_TOKEN startToken
, pANTLR3_COMMON_TOKEN stopToken
);
68 static ANTLR3_MARKER
getTokenStartIndex (pANTLR3_BASE_TREE_ADAPTOR adaptor
, pANTLR3_BASE_TREE t
);
69 static ANTLR3_MARKER
getTokenStopIndex (pANTLR3_BASE_TREE_ADAPTOR adaptor
, pANTLR3_BASE_TREE t
);
71 static void ctaFree (pANTLR3_BASE_TREE_ADAPTOR adaptor
);
73 /** Create a new tree adaptor. Note that despite the fact that this is
74 * creating a new COMMON_TREE adaptor, we return the address of the
75 * BASE_TREE interface, as should any other adaptor that wishes to be
76 * used as the tree element of a tree parse/build. It needs to be given the
77 * address of a valid string factory as we do not know what the originating
78 * input stream encoding type was. This way we can rely on just using
79 * the original input stream's string factory or one of the correct type
80 * which the user supplies us.
82 ANTLR3_API pANTLR3_BASE_TREE_ADAPTOR
83 ANTLR3_TREE_ADAPTORNew(pANTLR3_STRING_FACTORY strFactory
)
85 pANTLR3_COMMON_TREE_ADAPTOR cta
;
87 // First job is to create the memory we need for the tree adaptor interface.
89 cta
= (pANTLR3_COMMON_TREE_ADAPTOR
) ANTLR3_MALLOC((size_t)(sizeof(ANTLR3_COMMON_TREE_ADAPTOR
)));
96 // Memory is initialized, so initialize the base tree adaptor
98 antlr3BaseTreeAdaptorInit(&(cta
->baseAdaptor
), NULL
);
100 // Install our interface overrides. Strangeness is to allow generated code to treat them
101 // as returning void *
103 cta
->baseAdaptor
.dupNode
= (void * (*) (pANTLR3_BASE_TREE_ADAPTOR
, void *))
105 cta
->baseAdaptor
.create
= (void * (*) (pANTLR3_BASE_TREE_ADAPTOR
, pANTLR3_COMMON_TOKEN
))
107 cta
->baseAdaptor
.createToken
=
109 cta
->baseAdaptor
.createTokenFromToken
=
110 createTokenFromToken
;
111 cta
->baseAdaptor
.setTokenBoundaries
= (void (*) (pANTLR3_BASE_TREE_ADAPTOR
, void *, pANTLR3_COMMON_TOKEN
, pANTLR3_COMMON_TOKEN
))
113 cta
->baseAdaptor
.getTokenStartIndex
= (ANTLR3_MARKER (*) (pANTLR3_BASE_TREE_ADAPTOR
, void *))
115 cta
->baseAdaptor
.getTokenStopIndex
= (ANTLR3_MARKER (*) (pANTLR3_BASE_TREE_ADAPTOR
, void *))
117 cta
->baseAdaptor
.getText
= (pANTLR3_STRING (*) (pANTLR3_BASE_TREE_ADAPTOR
, void *))
119 cta
->baseAdaptor
.getType
= (ANTLR3_UINT32 (*) (pANTLR3_BASE_TREE_ADAPTOR
, void *))
121 cta
->baseAdaptor
.getChild
= (void * (*) (pANTLR3_BASE_TREE_ADAPTOR
, void *, ANTLR3_UINT32
))
123 cta
->baseAdaptor
.setChild
= (void (*) (pANTLR3_BASE_TREE_ADAPTOR
, void *, ANTLR3_UINT32
, void *))
125 cta
->baseAdaptor
.setParent
= (void (*) (pANTLR3_BASE_TREE_ADAPTOR
, void *, void *))
127 cta
->baseAdaptor
.getParent
= (void * (*) (pANTLR3_BASE_TREE_ADAPTOR
, void *))
129 cta
->baseAdaptor
.setChildIndex
= (void (*) (pANTLR3_BASE_TREE_ADAPTOR
, void *, ANTLR3_UINT32
))
131 cta
->baseAdaptor
.deleteChild
= (void (*) (pANTLR3_BASE_TREE_ADAPTOR
, void *, ANTLR3_UINT32
))
133 cta
->baseAdaptor
.getChildCount
= (ANTLR3_UINT32 (*) (pANTLR3_BASE_TREE_ADAPTOR
, void *))
135 cta
->baseAdaptor
.getChildIndex
= (ANTLR3_INT32 (*) (pANTLR3_BASE_TREE_ADAPTOR
, void *))
137 cta
->baseAdaptor
.free
= (void (*) (pANTLR3_BASE_TREE_ADAPTOR
))
139 cta
->baseAdaptor
.setDebugEventListener
=
140 setDebugEventListener
;
141 cta
->baseAdaptor
.replaceChildren
= (void (*) (pANTLR3_BASE_TREE_ADAPTOR
, void *, ANTLR3_INT32
, ANTLR3_INT32
, void *))
143 cta
->baseAdaptor
.errorNode
= (void * (*) (pANTLR3_BASE_TREE_ADAPTOR
, pANTLR3_TOKEN_STREAM
, pANTLR3_COMMON_TOKEN
, pANTLR3_COMMON_TOKEN
, pANTLR3_EXCEPTION
))
146 // Install the super class pointer
148 cta
->baseAdaptor
.super
= cta
;
150 // Install a tree factory for creating new tree nodes
152 cta
->arboretum
= antlr3ArboretumNew(strFactory
);
154 // Install a token factory for imaginary tokens, these imaginary
155 // tokens do not require access to the input stream so we can
156 // dummy the creation of it, but they will need a string factory.
158 cta
->baseAdaptor
.tokenFactory
= antlr3TokenFactoryNew(NULL
);
159 cta
->baseAdaptor
.tokenFactory
->unTruc
.strFactory
= strFactory
;
161 // Allow the base tree adaptor to share the tree factory's string factory.
163 cta
->baseAdaptor
.strFactory
= strFactory
;
165 // Return the address of the base adaptor interface.
167 return &(cta
->baseAdaptor
);
170 /// Debugging version of the tree adaptor (not normally called as generated code
171 /// calls setDebugEventListener instead which changes a normal token stream to
172 /// a debugging stream and means that a user's instantiation code does not need
173 /// to be changed just to debug with AW.
175 ANTLR3_API pANTLR3_BASE_TREE_ADAPTOR
176 ANTLR3_TREE_ADAPTORDebugNew(pANTLR3_STRING_FACTORY strFactory
, pANTLR3_DEBUG_EVENT_LISTENER debugger
)
178 pANTLR3_BASE_TREE_ADAPTOR ta
;
180 // Create a normal one first
182 ta
= ANTLR3_TREE_ADAPTORNew(strFactory
);
186 // Reinitialize as a debug version
188 antlr3BaseTreeAdaptorInit(ta
, debugger
);
189 ta
->create
= (void * (*) (pANTLR3_BASE_TREE_ADAPTOR
, pANTLR3_COMMON_TOKEN
))
191 ta
->setTokenBoundaries
= (void (*) (pANTLR3_BASE_TREE_ADAPTOR
, void *, pANTLR3_COMMON_TOKEN
, pANTLR3_COMMON_TOKEN
))
192 dbgSetTokenBoundaries
;
198 /// Causes an existing common tree adaptor to become a debug version
201 setDebugEventListener (pANTLR3_BASE_TREE_ADAPTOR adaptor
, pANTLR3_DEBUG_EVENT_LISTENER debugger
)
203 // Reinitialize as a debug version
205 antlr3BaseTreeAdaptorInit(adaptor
, debugger
);
207 adaptor
->create
= (void * (*) (pANTLR3_BASE_TREE_ADAPTOR
, pANTLR3_COMMON_TOKEN
))
209 adaptor
->setTokenBoundaries
= (void (*) (pANTLR3_BASE_TREE_ADAPTOR
, void *, pANTLR3_COMMON_TOKEN
, pANTLR3_COMMON_TOKEN
))
210 dbgSetTokenBoundaries
;
215 ctaFree(pANTLR3_BASE_TREE_ADAPTOR adaptor
)
217 pANTLR3_COMMON_TREE_ADAPTOR cta
;
219 cta
= (pANTLR3_COMMON_TREE_ADAPTOR
)(adaptor
->super
);
221 /* Free the tree factory we created
223 cta
->arboretum
->close(((pANTLR3_COMMON_TREE_ADAPTOR
)(adaptor
->super
))->arboretum
);
225 /* Free the token factory we created
227 adaptor
->tokenFactory
->close(adaptor
->tokenFactory
);
229 /* Free the super pointer, as it is this that was allocated
230 * and is the common tree structure.
232 ANTLR3_FREE(adaptor
->super
);
235 /* BASE_TREE_ADAPTOR overrides */
237 static pANTLR3_BASE_TREE
238 errorNode (pANTLR3_BASE_TREE_ADAPTOR adaptor
, pANTLR3_TOKEN_STREAM ctnstream
, pANTLR3_COMMON_TOKEN startToken
, pANTLR3_COMMON_TOKEN stopToken
, pANTLR3_EXCEPTION e
)
240 // Use the supplied common tree node stream to get another tree from the factory
241 // TODO: Look at creating the erronode as in Java, but this is complicated by the
242 // need to track and free the memory allocated to it, so for now, we just
243 // want something in the tree that isn't a NULL pointer.
245 return adaptor
->createTypeText(adaptor
, ANTLR3_TOKEN_INVALID
, (pANTLR3_UINT8
)"Tree Error Node");
249 /** Duplicate the supplied node.
251 static pANTLR3_BASE_TREE
252 dupNode (pANTLR3_BASE_TREE_ADAPTOR adaptor
, pANTLR3_BASE_TREE treeNode
)
254 return treeNode
== NULL
? NULL
: treeNode
->dupNode(treeNode
);
257 static pANTLR3_BASE_TREE
258 create (pANTLR3_BASE_TREE_ADAPTOR adaptor
, pANTLR3_COMMON_TOKEN payload
)
260 pANTLR3_BASE_TREE ct
;
262 /* Create a new common tree as this is what this adaptor deals with
264 ct
= ((pANTLR3_COMMON_TREE_ADAPTOR
)(adaptor
->super
))->arboretum
->newFromToken(((pANTLR3_COMMON_TREE_ADAPTOR
)(adaptor
->super
))->arboretum
, payload
);
266 /* But all adaptors return the pointer to the base interface.
270 static pANTLR3_BASE_TREE
271 dbgCreate (pANTLR3_BASE_TREE_ADAPTOR adaptor
, pANTLR3_COMMON_TOKEN payload
)
273 pANTLR3_BASE_TREE ct
;
275 ct
= create(adaptor
, payload
);
276 adaptor
->debugger
->createNode(adaptor
->debugger
, ct
);
281 /** Tell me how to create a token for use with imaginary token nodes.
282 * For example, there is probably no input symbol associated with imaginary
283 * token DECL, but you need to create it as a payload or whatever for
284 * the DECL node as in ^(DECL type ID).
286 * If you care what the token payload objects' type is, you should
287 * override this method and any other createToken variant.
289 static pANTLR3_COMMON_TOKEN
290 createToken (pANTLR3_BASE_TREE_ADAPTOR adaptor
, ANTLR3_UINT32 tokenType
, pANTLR3_UINT8 text
)
292 pANTLR3_COMMON_TOKEN newToken
;
294 newToken
= adaptor
->tokenFactory
->newToken(adaptor
->tokenFactory
);
296 if (newToken
!= NULL
)
298 newToken
->textState
= ANTLR3_TEXT_CHARP
;
299 newToken
->tokText
.chars
= (pANTLR3_UCHAR
)text
;
300 newToken
->type
= tokenType
;
301 newToken
->input
= adaptor
->tokenFactory
->input
;
302 newToken
->strFactory
= adaptor
->strFactory
;
307 /** Tell me how to create a token for use with imaginary token nodes.
308 * For example, there is probably no input symbol associated with imaginary
309 * token DECL, but you need to create it as a payload or whatever for
310 * the DECL node as in ^(DECL type ID).
312 * This is a variant of createToken where the new token is derived from
313 * an actual real input token. Typically this is for converting '{'
314 * tokens to BLOCK etc... You'll see
316 * r : lc='{' ID+ '}' -> ^(BLOCK[$lc] ID+) ;
318 * If you care what the token payload objects' type is, you should
319 * override this method and any other createToken variant.
321 * NB: this being C it is not so easy to extend the types of creaeteToken.
322 * We will have to see if anyone needs to do this and add any variants to
325 static pANTLR3_COMMON_TOKEN
326 createTokenFromToken (pANTLR3_BASE_TREE_ADAPTOR adaptor
, pANTLR3_COMMON_TOKEN fromToken
)
328 pANTLR3_COMMON_TOKEN newToken
;
330 newToken
= adaptor
->tokenFactory
->newToken(adaptor
->tokenFactory
);
332 if (newToken
!= NULL
)
334 // Create the text using our own string factory to avoid complicating
339 newToken
->toString
= fromToken
->toString
;
341 if (fromToken
->textState
== ANTLR3_TEXT_CHARP
)
343 newToken
->textState
= ANTLR3_TEXT_CHARP
;
344 newToken
->tokText
.chars
= fromToken
->tokText
.chars
;
348 text
= fromToken
->getText(fromToken
);
349 newToken
->textState
= ANTLR3_TEXT_STRING
;
350 newToken
->tokText
.text
= adaptor
->strFactory
->newPtr(adaptor
->strFactory
, text
->chars
, text
->len
);
353 newToken
->line
= fromToken
->line
;
354 newToken
->index
= fromToken
->index
;
355 newToken
->charPosition
= fromToken
->charPosition
;
356 newToken
->channel
= fromToken
->channel
;
357 newToken
->type
= fromToken
->type
;
363 /* Specific methods for a TreeAdaptor */
365 /** Track start/stop token for subtree root created for a rule.
366 * Only works with CommonTree nodes. For rules that match nothing,
367 * seems like this will yield start=i and stop=i-1 in a nil node.
368 * Might be useful info so I'll not force to be i..i.
371 setTokenBoundaries (pANTLR3_BASE_TREE_ADAPTOR adaptor
, pANTLR3_BASE_TREE t
, pANTLR3_COMMON_TOKEN startToken
, pANTLR3_COMMON_TOKEN stopToken
)
376 pANTLR3_COMMON_TREE ct
;
383 if ( startToken
!= NULL
)
385 start
= startToken
->index
;
392 if ( stopToken
!= NULL
)
394 stop
= stopToken
->index
;
401 ct
= (pANTLR3_COMMON_TREE
)(t
->super
);
403 ct
->startIndex
= start
;
404 ct
->stopIndex
= stop
;
408 dbgSetTokenBoundaries (pANTLR3_BASE_TREE_ADAPTOR adaptor
, pANTLR3_BASE_TREE t
, pANTLR3_COMMON_TOKEN startToken
, pANTLR3_COMMON_TOKEN stopToken
)
410 setTokenBoundaries(adaptor
, t
, startToken
, stopToken
);
412 if (t
!= NULL
&& startToken
!= NULL
&& stopToken
!= NULL
)
414 adaptor
->debugger
->setTokenBoundaries(adaptor
->debugger
, t
, startToken
->index
, stopToken
->index
);
419 getTokenStartIndex (pANTLR3_BASE_TREE_ADAPTOR adaptor
, pANTLR3_BASE_TREE t
)
421 return ((pANTLR3_COMMON_TREE
)(t
->super
))->startIndex
;
425 getTokenStopIndex (pANTLR3_BASE_TREE_ADAPTOR adaptor
, pANTLR3_BASE_TREE t
)
427 return ((pANTLR3_COMMON_TREE
)(t
->super
))->stopIndex
;
430 static pANTLR3_STRING
431 getText (pANTLR3_BASE_TREE_ADAPTOR adaptor
, pANTLR3_BASE_TREE t
)
433 return t
->getText(t
);
437 getType (pANTLR3_BASE_TREE_ADAPTOR adaptor
, pANTLR3_BASE_TREE t
)
439 return t
->getType(t
);
444 (pANTLR3_BASE_TREE_ADAPTOR adaptor
, pANTLR3_BASE_TREE parent
, ANTLR3_INT32 startChildIndex
, ANTLR3_INT32 stopChildIndex
, pANTLR3_BASE_TREE t
)
448 parent
->replaceChildren(parent
, startChildIndex
, stopChildIndex
, t
);
452 static pANTLR3_BASE_TREE
453 getChild (pANTLR3_BASE_TREE_ADAPTOR adaptor
, pANTLR3_BASE_TREE t
, ANTLR3_UINT32 i
)
455 return getBaseTreeChild(t
, i
);
458 setChild (pANTLR3_BASE_TREE_ADAPTOR adaptor
, pANTLR3_BASE_TREE t
, ANTLR3_UINT32 i
, pANTLR3_BASE_TREE child
)
460 setBaseTreeChild(t
, i
, child
);
464 deleteChild (pANTLR3_BASE_TREE_ADAPTOR adaptor
, pANTLR3_BASE_TREE t
, ANTLR3_UINT32 i
)
466 deleteBaseTreeChild(t
, i
);
470 getChildCount (pANTLR3_BASE_TREE_ADAPTOR adaptor
, pANTLR3_BASE_TREE t
)
472 return getBaseTreeChildCount(t
);
476 setChildIndex (pANTLR3_BASE_TREE_ADAPTOR adaptor
, pANTLR3_BASE_TREE t
, ANTLR3_INT32 i
)
478 t
->setChildIndex(t
, i
);
482 getChildIndex (pANTLR3_BASE_TREE_ADAPTOR adaptor
, pANTLR3_BASE_TREE t
)
484 return t
->getChildIndex(t
);
487 setParent (pANTLR3_BASE_TREE_ADAPTOR adaptor
, pANTLR3_BASE_TREE child
, pANTLR3_BASE_TREE parent
)
489 child
->setParent(child
, parent
);
491 static pANTLR3_BASE_TREE
492 getParent (pANTLR3_BASE_TREE_ADAPTOR adaptor
, pANTLR3_BASE_TREE child
)
494 return child
->getParent(child
);