1/// \file 2/// Implementation of token/tree streams that are used by the 3/// tree re-write rules to manipulate the tokens and trees produced 4/// by rules that are subject to rewrite directives. 5/// 6 7// [The "BSD licence"] 8// Copyright (c) 2005-2009 Jim Idle, Temporal Wave LLC 9// http://www.temporal-wave.com 10// http://www.linkedin.com/in/jimidle 11// 12// All rights reserved. 13// 14// Redistribution and use in source and binary forms, with or without 15// modification, are permitted provided that the following conditions 16// are met: 17// 1. Redistributions of source code must retain the above copyright 18// notice, this list of conditions and the following disclaimer. 19// 2. Redistributions in binary form must reproduce the above copyright 20// notice, this list of conditions and the following disclaimer in the 21// documentation and/or other materials provided with the distribution. 22// 3. The name of the author may not be used to endorse or promote products 23// derived from this software without specific prior written permission. 24// 25// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 26// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 27// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 28// IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 29// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 30// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 31// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 32// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 36#include <antlr3rewritestreams.h> 37 38// Static support function forward declarations for the stream types. 39// 40static void reset (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream); 41static void add (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream, void * el, void (ANTLR3_CDECL *freePtr)(void *)); 42static void * next (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream); 43static pANTLR3_BASE_TREE nextTree (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream); 44static void * nextToken (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream); 45static void * _next (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream); 46static void * dupTok (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream, void * el); 47static void * dupTree (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream, void * el); 48static void * dupTreeNode (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream, void * el); 49static pANTLR3_BASE_TREE toTree (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream, void * element); 50static pANTLR3_BASE_TREE toTreeNode (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream, void * element); 51static ANTLR3_BOOLEAN hasNext (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream); 52static pANTLR3_BASE_TREE nextNode (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream); 53static pANTLR3_BASE_TREE nextNodeNode (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream); 54static pANTLR3_BASE_TREE nextNodeToken (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream); 55static ANTLR3_UINT32 size (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream); 56static void * getDescription (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream); 57static void freeRS (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream); 58static void expungeRS (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream); 59 60 61// Place a now unused rewrite stream back on the rewrite stream pool 62// so we can reuse it if we need to. 63// 64static void 65freeRS (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream) 66{ 67 // Before placing the stream back in the pool, we 68 // need to clear any vector it has. This is so any 69 // free pointers that are associated with the 70 // entires are called. 71 // 72 if (stream->elements != NULL) 73 { 74 // Factory generated vectors can be returned to the 75 // vector factory for later reuse. 76 // 77 if (stream->elements->factoryMade == ANTLR3_TRUE) 78 { 79 pANTLR3_VECTOR_FACTORY factory = ((pANTLR3_COMMON_TREE_ADAPTOR)(stream->adaptor->super))->arboretum->vFactory; 80 factory->returnVector(factory, stream->elements); 81 82 stream->elements = NULL; 83 } 84 else 85 { 86 // Other vectors we clear and allow to be reused if they come off the 87 // rewrite stream free stack and are reused. 88 // 89 stream->elements->clear(stream->elements); 90 stream->freeElements = ANTLR3_TRUE; 91 } 92 } 93 else 94 { 95 stream->freeElements = ANTLR3_FALSE; // Just in case 96 } 97 98 // Add the stream into the recognizer stream stack vector 99 // adding the stream memory free routine so that 100 // it is thrown away when the stack vector is destroyed 101 // 102 stream->rec->state->rStreams->add(stream->rec->state->rStreams, stream, (void(*)(void *))expungeRS); 103} 104 105/** Do special nilNode reuse detection for node streams. 106 */ 107static void 108freeNodeRS(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream) 109{ 110 pANTLR3_BASE_TREE tree; 111 112 // Before placing the stream back in the pool, we 113 // need to clear any vector it has. This is so any 114 // free pointers that are associated with the 115 // entires are called. However, if this particular function is called 116 // then we know that the entries in the stream are definately 117 // tree nodes. Hence we check to see if any of them were nilNodes as 118 // if they were, we can reuse them. 119 // 120 if (stream->elements != NULL) 121 { 122 // We have some elements to traverse 123 // 124 ANTLR3_UINT32 i; 125 126 for (i = 1; i<= stream->elements->count; i++) 127 { 128 tree = (pANTLR3_BASE_TREE)(stream->elements->elements[i-1].element); 129 if (tree != NULL && tree->isNilNode(tree)) 130 { 131 // Had to remove this for now, check is not comprehensive enough 132 // tree->reuse(tree); 133 } 134 135 } 136 // Factory generated vectors can be returned to the 137 // vector factory for later reuse. 138 // 139 if (stream->elements->factoryMade == ANTLR3_TRUE) 140 { 141 pANTLR3_VECTOR_FACTORY factory = ((pANTLR3_COMMON_TREE_ADAPTOR)(stream->adaptor->super))->arboretum->vFactory; 142 factory->returnVector(factory, stream->elements); 143 144 stream->elements = NULL; 145 } 146 else 147 { 148 stream->elements->clear(stream->elements); 149 stream->freeElements = ANTLR3_TRUE; 150 } 151 } 152 else 153 { 154 if (stream->singleElement != NULL) 155 { 156 tree = (pANTLR3_BASE_TREE)(stream->singleElement); 157 if (tree->isNilNode(tree)) 158 { 159 // Had to remove this for now, check is not comprehensive enough 160 // tree->reuse(tree); 161 } 162 } 163 stream->singleElement = NULL; 164 stream->freeElements = ANTLR3_FALSE; // Just in case 165 } 166 167 // Add the stream into the recognizer stream stack vector 168 // adding the stream memory free routine so that 169 // it is thrown away when the stack vector is destroyed 170 // 171 stream->rec->state->rStreams->add(stream->rec->state->rStreams, stream, (void(*)(void *))expungeRS); 172} 173static void 174expungeRS(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream) 175{ 176 177 if (stream->freeElements == ANTLR3_TRUE && stream->elements != NULL) 178 { 179 stream->elements->free(stream->elements); 180 } 181 ANTLR3_FREE(stream); 182} 183 184// Functions for creating streams 185// 186static pANTLR3_REWRITE_RULE_ELEMENT_STREAM 187antlr3RewriteRuleElementStreamNewAE(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_RECOGNIZER rec, pANTLR3_UINT8 description) 188{ 189 pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream; 190 191 // First - do we already have a rewrite stream that was returned 192 // to the pool? If we do, then we will just reuse it by resetting 193 // the generic interface. 194 // 195 if (rec->state->rStreams->count > 0) 196 { 197 // Remove the entry from the vector. We do not 198 // cause it to be freed by using remove. 199 // 200 stream = rec->state->rStreams->remove(rec->state->rStreams, rec->state->rStreams->count - 1); 201 202 // We found a stream we can reuse. 203 // If the stream had a vector, then it will have been cleared 204 // when the freeRS was called that put it in this stack 205 // 206 } 207 else 208 { 209 // Ok, we need to allocate a new one as there were none on the stack. 210 // First job is to create the memory we need. 211 // 212 stream = (pANTLR3_REWRITE_RULE_ELEMENT_STREAM) ANTLR3_MALLOC((size_t)(sizeof(ANTLR3_REWRITE_RULE_ELEMENT_STREAM))); 213 214 if (stream == NULL) 215 { 216 return NULL; 217 } 218 stream->elements = NULL; 219 stream->freeElements = ANTLR3_FALSE; 220 } 221 222 // Populate the generic interface 223 // 224 stream->rec = rec; 225 stream->reset = reset; 226 stream->add = add; 227 stream->next = next; 228 stream->nextTree = nextTree; 229 stream->nextNode = nextNode; 230 stream->nextToken = nextToken; 231 stream->_next = _next; 232 stream->hasNext = hasNext; 233 stream->size = size; 234 stream->getDescription = getDescription; 235 stream->toTree = toTree; 236 stream->free = freeRS; 237 stream->singleElement = NULL; 238 239 // Reset the stream to empty. 240 // 241 242 stream->cursor = 0; 243 stream->dirty = ANTLR3_FALSE; 244 245 // Install the description 246 // 247 stream->elementDescription = description; 248 249 // Install the adaptor 250 // 251 stream->adaptor = adaptor; 252 253 return stream; 254} 255 256static pANTLR3_REWRITE_RULE_ELEMENT_STREAM 257antlr3RewriteRuleElementStreamNewAEE(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_RECOGNIZER rec, pANTLR3_UINT8 description, void * oneElement) 258{ 259 pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream; 260 261 // First job is to create the memory we need. 262 // 263 stream = antlr3RewriteRuleElementStreamNewAE(adaptor, rec, description); 264 265 if (stream == NULL) 266 { 267 return NULL; 268 } 269 270 // Stream seems good so we need to add the supplied element 271 // 272 if (oneElement != NULL) 273 { 274 stream->add(stream, oneElement, NULL); 275 } 276 return stream; 277} 278 279static pANTLR3_REWRITE_RULE_ELEMENT_STREAM 280antlr3RewriteRuleElementStreamNewAEV(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_RECOGNIZER rec, pANTLR3_UINT8 description, pANTLR3_VECTOR vector) 281{ 282 pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream; 283 284 // First job is to create the memory we need. 285 // 286 stream = antlr3RewriteRuleElementStreamNewAE(adaptor, rec, description); 287 288 if (stream == NULL) 289 { 290 return stream; 291 } 292 293 // Stream seems good so we need to install the vector we were 294 // given. We assume that someone else is going to free the 295 // vector. 296 // 297 if (stream->elements != NULL && stream->elements->factoryMade == ANTLR3_FALSE && stream->freeElements == ANTLR3_TRUE ) 298 { 299 stream->elements->free(stream->elements); 300 } 301 stream->elements = vector; 302 stream->freeElements = ANTLR3_FALSE; 303 return stream; 304} 305 306// Token rewrite stream ... 307// 308ANTLR3_API pANTLR3_REWRITE_RULE_TOKEN_STREAM 309antlr3RewriteRuleTOKENStreamNewAE(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_RECOGNIZER rec, pANTLR3_UINT8 description) 310{ 311 pANTLR3_REWRITE_RULE_TOKEN_STREAM stream; 312 313 // First job is to create the memory we need. 314 // 315 stream = antlr3RewriteRuleElementStreamNewAE(adaptor, rec, description); 316 317 if (stream == NULL) 318 { 319 return stream; 320 } 321 322 // Install the token based overrides 323 // 324 stream->dup = dupTok; 325 stream->nextNode = nextNodeToken; 326 327 // No nextNode implementation for a token rewrite stream 328 // 329 return stream; 330} 331 332ANTLR3_API pANTLR3_REWRITE_RULE_TOKEN_STREAM 333antlr3RewriteRuleTOKENStreamNewAEE(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_RECOGNIZER rec, pANTLR3_UINT8 description, void * oneElement) 334{ 335 pANTLR3_REWRITE_RULE_TOKEN_STREAM stream; 336 337 // First job is to create the memory we need. 338 // 339 stream = antlr3RewriteRuleElementStreamNewAEE(adaptor, rec, description, oneElement); 340 341 // Install the token based overrides 342 // 343 stream->dup = dupTok; 344 stream->nextNode = nextNodeToken; 345 346 // No nextNode implementation for a token rewrite stream 347 // 348 return stream; 349} 350 351ANTLR3_API pANTLR3_REWRITE_RULE_TOKEN_STREAM 352antlr3RewriteRuleTOKENStreamNewAEV(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_RECOGNIZER rec, pANTLR3_UINT8 description, pANTLR3_VECTOR vector) 353{ 354 pANTLR3_REWRITE_RULE_TOKEN_STREAM stream; 355 356 // First job is to create the memory we need. 357 // 358 stream = antlr3RewriteRuleElementStreamNewAEV(adaptor, rec, description, vector); 359 360 // Install the token based overrides 361 // 362 stream->dup = dupTok; 363 stream->nextNode = nextNodeToken; 364 365 // No nextNode implementation for a token rewrite stream 366 // 367 return stream; 368} 369 370// Subtree rewrite stream 371// 372ANTLR3_API pANTLR3_REWRITE_RULE_SUBTREE_STREAM 373antlr3RewriteRuleSubtreeStreamNewAE(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_RECOGNIZER rec, pANTLR3_UINT8 description) 374{ 375 pANTLR3_REWRITE_RULE_SUBTREE_STREAM stream; 376 377 // First job is to create the memory we need. 378 // 379 stream = antlr3RewriteRuleElementStreamNewAE(adaptor, rec, description); 380 381 if (stream == NULL) 382 { 383 return stream; 384 } 385 386 // Install the subtree based overrides 387 // 388 stream->dup = dupTree; 389 stream->nextNode = nextNode; 390 stream->free = freeNodeRS; 391 return stream; 392 393} 394ANTLR3_API pANTLR3_REWRITE_RULE_SUBTREE_STREAM 395antlr3RewriteRuleSubtreeStreamNewAEE(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_RECOGNIZER rec, pANTLR3_UINT8 description, void * oneElement) 396{ 397 pANTLR3_REWRITE_RULE_SUBTREE_STREAM stream; 398 399 // First job is to create the memory we need. 400 // 401 stream = antlr3RewriteRuleElementStreamNewAEE(adaptor, rec, description, oneElement); 402 403 if (stream == NULL) 404 { 405 return stream; 406 } 407 408 // Install the subtree based overrides 409 // 410 stream->dup = dupTree; 411 stream->nextNode = nextNode; 412 stream->free = freeNodeRS; 413 414 return stream; 415} 416 417ANTLR3_API pANTLR3_REWRITE_RULE_SUBTREE_STREAM 418antlr3RewriteRuleSubtreeStreamNewAEV(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_RECOGNIZER rec, pANTLR3_UINT8 description, pANTLR3_VECTOR vector) 419{ 420 pANTLR3_REWRITE_RULE_SUBTREE_STREAM stream; 421 422 // First job is to create the memory we need. 423 // 424 stream = antlr3RewriteRuleElementStreamNewAEV(adaptor, rec, description, vector); 425 426 if (stream == NULL) 427 { 428 return NULL; 429 } 430 431 // Install the subtree based overrides 432 // 433 stream->dup = dupTree; 434 stream->nextNode = nextNode; 435 stream->free = freeNodeRS; 436 437 return stream; 438} 439// Node rewrite stream ... 440// 441ANTLR3_API pANTLR3_REWRITE_RULE_NODE_STREAM 442antlr3RewriteRuleNODEStreamNewAE(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_RECOGNIZER rec, pANTLR3_UINT8 description) 443{ 444 pANTLR3_REWRITE_RULE_NODE_STREAM stream; 445 446 // First job is to create the memory we need. 447 // 448 stream = antlr3RewriteRuleElementStreamNewAE(adaptor, rec, description); 449 450 if (stream == NULL) 451 { 452 return stream; 453 } 454 455 // Install the node based overrides 456 // 457 stream->dup = dupTreeNode; 458 stream->toTree = toTreeNode; 459 stream->nextNode = nextNodeNode; 460 stream->free = freeNodeRS; 461 462 return stream; 463} 464 465ANTLR3_API pANTLR3_REWRITE_RULE_NODE_STREAM 466antlr3RewriteRuleNODEStreamNewAEE(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_RECOGNIZER rec, pANTLR3_UINT8 description, void * oneElement) 467{ 468 pANTLR3_REWRITE_RULE_NODE_STREAM stream; 469 470 // First job is to create the memory we need. 471 // 472 stream = antlr3RewriteRuleElementStreamNewAEE(adaptor, rec, description, oneElement); 473 474 // Install the node based overrides 475 // 476 stream->dup = dupTreeNode; 477 stream->toTree = toTreeNode; 478 stream->nextNode = nextNodeNode; 479 stream->free = freeNodeRS; 480 481 return stream; 482} 483 484ANTLR3_API pANTLR3_REWRITE_RULE_NODE_STREAM 485antlr3RewriteRuleNODEStreamNewAEV(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_RECOGNIZER rec, pANTLR3_UINT8 description, pANTLR3_VECTOR vector) 486{ 487 pANTLR3_REWRITE_RULE_NODE_STREAM stream; 488 489 // First job is to create the memory we need. 490 // 491 stream = antlr3RewriteRuleElementStreamNewAEV(adaptor, rec, description, vector); 492 493 // Install the Node based overrides 494 // 495 stream->dup = dupTreeNode; 496 stream->toTree = toTreeNode; 497 stream->nextNode = nextNodeNode; 498 stream->free = freeNodeRS; 499 500 return stream; 501} 502 503//---------------------------------------------------------------------- 504// Static support functions 505 506/// Reset the condition of this stream so that it appears we have 507/// not consumed any of its elements. Elements themselves are untouched. 508/// 509static void 510reset (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream) 511{ 512 stream->dirty = ANTLR3_TRUE; 513 stream->cursor = 0; 514} 515 516// Add a new pANTLR3_BASE_TREE to this stream 517// 518static void 519add (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream, void * el, void (ANTLR3_CDECL *freePtr)(void *)) 520{ 521 if (el== NULL) 522 { 523 return; 524 } 525 // As we may be reusing a stream, we may already have allocated 526 // a rewrite stream vector. If we have then is will be empty if 527 // we have either zero or just one element in the rewrite stream 528 // 529 if (stream->elements != NULL && stream->elements->count > 0) 530 { 531 // We already have >1 entries in the stream. So we can just add this new element to the existing 532 // collection. 533 // 534 stream->elements->add(stream->elements, el, freePtr); 535 return; 536 } 537 if (stream->singleElement == NULL) 538 { 539 stream->singleElement = el; 540 return; 541 } 542 543 // If we got here then we had only the one element so far 544 // and we must now create a vector to hold a collection of them 545 // 546 if (stream->elements == NULL) 547 { 548 pANTLR3_VECTOR_FACTORY factory = ((pANTLR3_COMMON_TREE_ADAPTOR)(stream->adaptor->super))->arboretum->vFactory; 549 550 551 stream->elements = factory->newVector(factory); 552 stream->freeElements = ANTLR3_TRUE; // We 'ummed it, so we play it son. 553 } 554 555 stream->elements->add (stream->elements, stream->singleElement, freePtr); 556 stream->elements->add (stream->elements, el, freePtr); 557 stream->singleElement = NULL; 558 559 return; 560} 561 562/// Return the next element in the stream. If out of elements, throw 563/// an exception unless size()==1. If size is 1, then return elements[0]. 564/// Return a duplicate node/subtree if stream is out of elements and 565/// size==1. If we've already used the element, dup (dirty bit set). 566/// 567static pANTLR3_BASE_TREE 568nextTree(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream) 569{ 570 ANTLR3_UINT32 n; 571 void * el; 572 573 n = stream->size(stream); 574 575 if ( stream->dirty || (stream->cursor >=n && n==1) ) 576 { 577 // if out of elements and size is 1, dup 578 // 579 el = stream->_next(stream); 580 return stream->dup(stream, el); 581 } 582 583 // test size above then fetch 584 // 585 el = stream->_next(stream); 586 return el; 587} 588 589/// Return the next element for a caller that wants just the token 590/// 591static void * 592nextToken (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream) 593{ 594 return stream->_next(stream); 595} 596 597/// Return the next element in the stream. If out of elements, throw 598/// an exception unless size()==1. If size is 1, then return elements[0]. 599/// 600static void * 601next (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream) 602{ 603 ANTLR3_UINT32 s; 604 605 s = stream->size(stream); 606 if (stream->cursor >= s && s == 1) 607 { 608 pANTLR3_BASE_TREE el; 609 610 el = stream->_next(stream); 611 612 return stream->dup(stream, el); 613 } 614 615 return stream->_next(stream); 616} 617 618/// Do the work of getting the next element, making sure that it's 619/// a tree node or subtree. Deal with the optimization of single- 620/// element list versus list of size > 1. Throw an exception (or something similar) 621/// if the stream is empty or we're out of elements and size>1. 622/// You can override in a 'subclass' if necessary. 623/// 624static void * 625_next (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream) 626{ 627 ANTLR3_UINT32 n; 628 pANTLR3_BASE_TREE t; 629 630 n = stream->size(stream); 631 632 if (n == 0) 633 { 634 // This means that the stream is empty 635 // 636 return NULL; // Caller must cope with this 637 } 638 639 // Traversed all the available elements already? 640 // 641 if (stream->cursor >= n) 642 { 643 if (n == 1) 644 { 645 // Special case when size is single element, it will just dup a lot 646 // 647 return stream->toTree(stream, stream->singleElement); 648 } 649 650 // Out of elements and the size is not 1, so we cannot assume 651 // that we just duplicate the entry n times (such as ID ent+ -> ^(ID ent)+) 652 // This means we ran out of elements earlier than was expected. 653 // 654 return NULL; // Caller must cope with this 655 } 656 657 // Elements available either for duping or just available 658 // 659 if (stream->singleElement != NULL) 660 { 661 stream->cursor++; // Cursor advances even for single element as this tells us to dup() 662 return stream->toTree(stream, stream->singleElement); 663 } 664 665 // More than just a single element so we extract it from the 666 // vector. 667 // 668 t = stream->toTree(stream, stream->elements->get(stream->elements, stream->cursor)); 669 stream->cursor++; 670 return t; 671} 672 673#ifdef ANTLR3_WINDOWS 674#pragma warning(push) 675#pragma warning(disable : 4100) 676#endif 677/// When constructing trees, sometimes we need to dup a token or AST 678/// subtree. Dup'ing a token means just creating another AST node 679/// around it. For trees, you must call the adaptor.dupTree(). 680/// 681static void * 682dupTok (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream, void * el) 683{ 684 ANTLR3_FPRINTF(stderr, "dup() cannot be called on a token rewrite stream!!"); 685 return NULL; 686} 687#ifdef ANTLR3_WINDOWS 688#pragma warning(pop) 689#endif 690 691/// When constructing trees, sometimes we need to dup a token or AST 692/// subtree. Dup'ing a token means just creating another AST node 693/// around it. For trees, you must call the adaptor.dupTree(). 694/// 695static void * 696dupTree (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream, void * element) 697{ 698 return stream->adaptor->dupNode(stream->adaptor, (pANTLR3_BASE_TREE)element); 699} 700 701#ifdef ANTLR3_WINDOWS 702#pragma warning(push) 703#pragma warning(disable : 4100) 704#endif 705/// When constructing trees, sometimes we need to dup a token or AST 706/// subtree. Dup'ing a token means just creating another AST node 707/// around it. For trees, you must call the adaptor.dupTree(). 708/// 709static void * 710dupTreeNode (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream, void * element) 711{ 712 ANTLR3_FPRINTF(stderr, "dup() cannot be called on a node rewrite stream!!!"); 713 return NULL; 714} 715 716 717/// We don;t explicitly convert to a tree unless the call goes to 718/// nextTree, which means rewrites are heterogeneous 719/// 720static pANTLR3_BASE_TREE 721toTree (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream, void * element) 722{ 723 return (pANTLR3_BASE_TREE)element; 724} 725#ifdef ANTLR3_WINDOWS 726#pragma warning(pop) 727#endif 728 729/// Ensure stream emits trees; tokens must be converted to AST nodes. 730/// AST nodes can be passed through unmolested. 731/// 732#ifdef ANTLR3_WINDOWS 733#pragma warning(push) 734#pragma warning(disable : 4100) 735#endif 736 737static pANTLR3_BASE_TREE 738toTreeNode (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream, void * element) 739{ 740 return stream->adaptor->dupNode(stream->adaptor, (pANTLR3_BASE_TREE)element); 741} 742 743#ifdef ANTLR3_WINDOWS 744#pragma warning(pop) 745#endif 746 747/// Returns ANTLR3_TRUE if there is a next element available 748/// 749static ANTLR3_BOOLEAN 750hasNext (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream) 751{ 752 if ( (stream->singleElement != NULL && stream->cursor < 1) 753 || (stream->elements != NULL && stream->cursor < stream->elements->size(stream->elements))) 754 { 755 return ANTLR3_TRUE; 756 } 757 else 758 { 759 return ANTLR3_FALSE; 760 } 761} 762 763/// Get the next token from the list and create a node for it 764/// This is the implementation for token streams. 765/// 766static pANTLR3_BASE_TREE 767nextNodeToken(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream) 768{ 769 return stream->adaptor->create(stream->adaptor, stream->_next(stream)); 770} 771 772static pANTLR3_BASE_TREE 773nextNodeNode(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream) 774{ 775 return stream->_next(stream); 776} 777 778/// Treat next element as a single node even if it's a subtree. 779/// This is used instead of next() when the result has to be a 780/// tree root node. Also prevents us from duplicating recently-added 781/// children; e.g., ^(type ID)+ adds ID to type and then 2nd iteration 782/// must dup the type node, but ID has been added. 783/// 784/// Referencing to a rule result twice is ok; dup entire tree as 785/// we can't be adding trees; e.g., expr expr. 786/// 787static pANTLR3_BASE_TREE 788nextNode (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream) 789{ 790 791 ANTLR3_UINT32 n; 792 pANTLR3_BASE_TREE el = stream->_next(stream); 793 794 n = stream->size(stream); 795 if (stream->dirty == ANTLR3_TRUE || (stream->cursor > n && n == 1)) 796 { 797 // We are out of elements and the size is 1, which means we just 798 // dup the node that we have 799 // 800 return stream->adaptor->dupNode(stream->adaptor, el); 801 } 802 803 // We were not out of nodes, so the one we received is the one to return 804 // 805 return el; 806} 807 808/// Number of elements available in the stream 809/// 810static ANTLR3_UINT32 811size (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream) 812{ 813 ANTLR3_UINT32 n = 0; 814 815 /// Should be a count of one if singleElement is set. I copied this 816 /// logic from the java implementation, which I suspect is just guarding 817 /// against someone setting singleElement and forgetting to NULL it out 818 /// 819 if (stream->singleElement != NULL) 820 { 821 n = 1; 822 } 823 else 824 { 825 if (stream->elements != NULL) 826 { 827 return (ANTLR3_UINT32)(stream->elements->count); 828 } 829 } 830 return n; 831} 832 833/// Returns the description string if there is one available (check for NULL). 834/// 835static void * 836getDescription (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream) 837{ 838 if (stream->elementDescription == NULL) 839 { 840 stream->elementDescription = "<unknown source>"; 841 } 842 843 return stream->elementDescription; 844} 845