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 // 40 static void reset (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream); 41 static void add (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream, void * el, void (ANTLR3_CDECL *freePtr)(void *)); 42 static void * next (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream); 43 static pANTLR3_BASE_TREE nextTree (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream); 44 static void * nextToken (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream); 45 static void * _next (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream); 46 static void * dupTok (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream, void * el); 47 static void * dupTree (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream, void * el); 48 static void * dupTreeNode (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream, void * el); 49 static pANTLR3_BASE_TREE toTree (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream, void * element); 50 static pANTLR3_BASE_TREE toTreeNode (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream, void * element); 51 static ANTLR3_BOOLEAN hasNext (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream); 52 static pANTLR3_BASE_TREE nextNode (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream); 53 static pANTLR3_BASE_TREE nextNodeNode (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream); 54 static pANTLR3_BASE_TREE nextNodeToken (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream); 55 static ANTLR3_UINT32 size (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream); 56 static void * getDescription (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream); 57 static void freeRS (pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream); 58 static 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 // 64 static void 65 freeRS (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 */ 107 static void 108 freeNodeRS(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 } 173 static void 174 expungeRS(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 // 186 static pANTLR3_REWRITE_RULE_ELEMENT_STREAM 187 antlr3RewriteRuleElementStreamNewAE(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 256 static pANTLR3_REWRITE_RULE_ELEMENT_STREAM 257 antlr3RewriteRuleElementStreamNewAEE(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 279 static pANTLR3_REWRITE_RULE_ELEMENT_STREAM 280 antlr3RewriteRuleElementStreamNewAEV(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 // 308 ANTLR3_API pANTLR3_REWRITE_RULE_TOKEN_STREAM 309 antlr3RewriteRuleTOKENStreamNewAE(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 332 ANTLR3_API pANTLR3_REWRITE_RULE_TOKEN_STREAM 333 antlr3RewriteRuleTOKENStreamNewAEE(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 351 ANTLR3_API pANTLR3_REWRITE_RULE_TOKEN_STREAM 352 antlr3RewriteRuleTOKENStreamNewAEV(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 // 372 ANTLR3_API pANTLR3_REWRITE_RULE_SUBTREE_STREAM 373 antlr3RewriteRuleSubtreeStreamNewAE(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 } 394 ANTLR3_API pANTLR3_REWRITE_RULE_SUBTREE_STREAM 395 antlr3RewriteRuleSubtreeStreamNewAEE(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 417 ANTLR3_API pANTLR3_REWRITE_RULE_SUBTREE_STREAM 418 antlr3RewriteRuleSubtreeStreamNewAEV(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 // 441 ANTLR3_API pANTLR3_REWRITE_RULE_NODE_STREAM 442 antlr3RewriteRuleNODEStreamNewAE(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 465 ANTLR3_API pANTLR3_REWRITE_RULE_NODE_STREAM 466 antlr3RewriteRuleNODEStreamNewAEE(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 484 ANTLR3_API pANTLR3_REWRITE_RULE_NODE_STREAM 485 antlr3RewriteRuleNODEStreamNewAEV(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 /// 509 static void 510 reset (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 // 518 static void 519 add (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 /// 567 static pANTLR3_BASE_TREE 568 nextTree(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 /// 591 static void * 592 nextToken (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 /// 600 static void * 601 next (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 /// 624 static 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 /// 681 static void * 682 dupTok (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 /// 695 static void * 696 dupTree (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 /// 709 static void * 710 dupTreeNode (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 /// 720 static pANTLR3_BASE_TREE 721 toTree (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 737 static pANTLR3_BASE_TREE 738 toTreeNode (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 /// 749 static ANTLR3_BOOLEAN 750 hasNext (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 /// 766 static pANTLR3_BASE_TREE 767 nextNodeToken(pANTLR3_REWRITE_RULE_ELEMENT_STREAM stream) 768 { 769 return stream->adaptor->create(stream->adaptor, stream->_next(stream)); 770 } 771 772 static pANTLR3_BASE_TREE 773 nextNodeNode(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 /// 787 static pANTLR3_BASE_TREE 788 nextNode (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 /// 810 static ANTLR3_UINT32 811 size (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 /// 835 static void * 836 getDescription (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