1/* 2 [The "BSD license"] 3 Copyright (c) 2005-2009 Jim Idle, Temporal Wave LLC 4 http://www.temporal-wave.com 5 http://www.linkedin.com/in/jimidle 6 7 All rights reserved. 8 9 Redistribution and use in source and binary forms, with or without 10 modification, are permitted provided that the following conditions 11 are met: 12 1. Redistributions of source code must retain the above copyright 13 notice, this list of conditions and the following disclaimer. 14 2. Redistributions in binary form must reproduce the above copyright 15 notice, this list of conditions and the following disclaimer in the 16 documentation and/or other materials provided with the distribution. 17 3. The name of the author may not be used to endorse or promote products 18 derived from this software without specific prior written permission. 19 20 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 21 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 22 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 23 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 24 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 25 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 29 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30*/ 31/** Add an adaptor property that knows how to build trees */ 32@headerFile.members() ::= << 33/* @headerFile.members() */ 34pANTLR3_BASE_TREE_ADAPTOR adaptor; 35pANTLR3_VECTOR_FACTORY vectors; 36/* End @headerFile.members() */ 37>> 38 39/** Install the tree adaptor interface pointer and anything else that 40 * tree parsers and producers require. 41 */ 42@genericParser.apifuncs() ::= << 43<if(PARSER)> 44ADAPTOR = ANTLR3_TREE_ADAPTORNew(instream->tstream->tokenSource->strFactory);<\n> 45<endif> 46ctx->vectors = antlr3VectorFactoryNew(0); 47>> 48 49@genericParser.cleanup() ::= << 50ctx->vectors->close(ctx->vectors); 51<if(PARSER)> 52/* We created the adaptor so we must free it 53 */ 54ADAPTOR->free(ADAPTOR); 55<endif> 56>> 57 58@returnScope.ruleReturnMembers() ::= << 59 60<super.ASTLabelType()> tree; 61 62>> 63 64/** Add a variable to track rule's return AST */ 65ruleDeclarations() ::= << 66<super.ruleDeclarations()> 67<ASTLabelType> root_0;<\n> 68>> 69 70ruleInitializations() ::= << 71<super.ruleInitializations()> 72root_0 = NULL;<\n> 73>> 74 75ruleLabelDefs() ::= << 76<super.ruleLabelDefs()> 77<ruleDescriptor.tokenLabels:{it | <ASTLabelType> <it.label.text>_tree;}; separator="\n"> 78<ruleDescriptor.tokenListLabels:{it | <ASTLabelType> <it.label.text>_tree;}; separator="\n"> 79<ruleDescriptor.allTokenRefsInAltsWithRewrites 80 :{it | pANTLR3_REWRITE_RULE_<rewriteElementType>_STREAM stream_<it>;}; separator="\n"> 81<ruleDescriptor.allRuleRefsInAltsWithRewrites 82 :{it | pANTLR3_REWRITE_RULE_SUBTREE_STREAM stream_<it>;}; separator="\n"> 83>> 84 85/* Note that we defer the actual creation of any rewrite streams we need here and just initialize 86 * them to NULL. This saves creating huge numbers of rewrite streams that cannot be used as only 87 * one alt will be taken in a rule, but we are declaring all the streams here. So we define 88 * a macro that conatins the create code, then use this macro later to check if the stream 89 * has been created yet. Checking for NULL is almost free in C. 90 */ 91ruleLabelInitializations() ::= << 92<super.ruleLabelInitializations()> 93<ruleDescriptor.tokenLabels:{it | <it.label.text>_tree = NULL;}; separator="\n"> 94<ruleDescriptor.tokenListLabels:{it | <it.label.text>_tree = NULL;}; separator="\n"> 95 96<ruleDescriptor.allTokenRefsInAltsWithRewrites 97:{it | stream_<it> = NULL; 98#define CREATE_stream_<it> if (stream_<it> == NULL) {stream_<it> = antlr3RewriteRule<rewriteElementType>StreamNewAE(ADAPTOR, RECOGNIZER, (pANTLR3_UINT8)"token <it>"); \} }; separator="\n"> 99<ruleDescriptor.allRuleRefsInAltsWithRewrites 100:{it | stream_<it> = NULL; 101#define CREATE_stream_<it> if (stream_<it> == NULL) {stream_<it> = antlr3RewriteRuleSubtreeStreamNewAE(ADAPTOR, RECOGNIZER, (pANTLR3_UINT8)"rule <it>"); \}}; separator="\n"> 102 103<if(ruleDescriptor.hasMultipleReturnValues)> 104retval.tree = NULL; 105<endif> 106>> 107 108 109/** a rule label including default value */ 110ruleLabelInitVal(label) ::= << 111<super.ruleLabelInitVal(...)> 112<label.label.text>.tree = NULL; 113>> 114 115/** When doing auto AST construction, we must define some variables; 116 * These should be turned off if doing rewrites. This must be a "mode" 117 * as a rule could have both rewrite and AST within the same alternative 118 * block. 119 */ 120@alt.declarations() ::= << 121<if(autoAST)> 122<if(outerAlt)> 123<endif> 124<endif> 125>> 126 127@alt.initializations() ::= << 128<if(autoAST)> 129<if(outerAlt)> 130<if(!rewriteMode)> 131root_0 = (<ASTLabelType>)(ADAPTOR->nilNode(ADAPTOR));<\n> 132<endif> 133<endif> 134<endif> 135>> 136 137 138// T r a c k i n g R u l e E l e m e n t s 139// 140/** ID but track it for use in a rewrite rule */ 141tokenRefTrack(token,label,elementIndex,terminalOptions) ::= << 142<tokenRefBang(...)> <! Track implies no auto AST construction!> 143<if(backtracking)>if ( <actions.(actionScope).synpredgate> ) { <endif>CREATE_stream_<token>; stream_<token>->add(stream_<token>, <label>, NULL);<if(backtracking)> }<endif><\n> 144>> 145 146/** ids+=ID and track it for use in a rewrite rule; adds to ids *and* 147 * to the tracking list stream_ID for use in the rewrite. 148 */ 149tokenRefTrackAndListLabel(token,label,elementIndex,terminalOptions) ::= << 150<tokenRefTrack(...)> 151<listLabel(elem=label,...)> 152>> 153 154/** ^(ID ...) track for rewrite */ 155tokenRefRuleRootTrack(token,label,elementIndex,terminalOptions) ::= << 156<tokenRefBang(...)> 157<if(backtracking)>if ( <actions.(actionScope).synpredgate> ) {<endif>CREATE_stream_<token>; stream_<token>->add(stream_<token>, <label>, NULL);<if(backtracking)> }<endif><\n> 158>> 159 160wildcardTrack(label,elementIndex) ::= << 161<super.wildcard(...)> 162>> 163 164/** rule when output=AST and tracking for rewrite */ 165ruleRefTrack(rule,label,elementIndex,args,scope) ::= << 166<super.ruleRef(...)> 167<if(backtracking)>if ( <actions.(actionScope).synpredgate> ) { <endif>CREATE_stream_<rule.name>; stream_<rule.name>->add(stream_<rule.name>, <label>.tree, NULL);<if(backtracking)> }<endif> 168>> 169 170/** x+=rule when output=AST and tracking for rewrite */ 171ruleRefTrackAndListLabel(rule,label,elementIndex,args,scope) ::= << 172<ruleRefTrack(...)> 173<listLabelTrack(...)> 174>> 175 176/** ^(rule ...) rewrite */ 177ruleRefRuleRootTrack(rule,label,elementIndex,args,scope) ::= << 178<ruleRefRuleRoot(...)> 179<if(backtracking)>if ( <actions.(actionScope).synpredgate> ) { <endif>CREATE_stream_<rule.name>; stream_<rule.name>->add(stream_<rule.name>, <label>.tree, NULL);<if(backtracking)> }<endif> 180>> 181 182/** ^(x+=rule ...) rewrite */ 183ruleRefRuleRootTrackAndListLabel(rule,label,elementIndex,args,scope) ::= << 184<ruleRefRuleRootTrack(...)> 185<listLabelAST(...)> 186>> 187 188 189// RULE REF AST 190 191 192 193/** Match ^(label+=TOKEN ...) track for rewrite */ 194tokenRefRuleRootTrackAndListLabel(token,label,elementIndex,terminalOptions) ::= << 195<tokenRefRuleRootTrack(...)> 196<listLabel(elem=label,...)> 197>> 198 199 200/* How to accumulate lists when we are doing rewrite tracking... 201 */ 202listLabelTrack(label) ::= << 203/* listLabelTrack(label) 204 */ 205if (list_<label> == NULL) 206{ 207 list_<label>=ctx->vectors->newVector(ctx->vectors); 208} 209list_<label>->add(list_<label>, <label>.tree, NULL); 210>> 211 212/* How to accumulate lists of rule outputs (only allowed with AST 213 * option but if the user is going to walk the tree, they will want 214 * all their custom elements from rule returns. 215 * 216 * Normally, we use inline structures (which the compiler lays down 217 * code to copy from heap allocations. However, here we want to accumulate copies 218 * of the returned structures because we are adding them to a list. This only makes sense if the 219 * grammar is not rewriting the tree as a tree rewrite only preserves the tree, not the object/structure 220 * returned from the rule. The rewrite will extract the tree pointer. However, if we are not going to 221 * do a tree re-write, then the user may wish to iterate the structures returned by the rule in 222 * action code and will expect the user defined returns[] elements to be available when they do this. 223 * Hence we cannot just preserve the tree that was returned. So, we must copy the local structure and provide 224 * a function that can free the allocated space. We cannot know how to free user allocated elements and 225 * presume that the user will know to do this using their own factories for the structures they allocate. 226 */ 227listLabelAST(label) ::= << 228if (list_<label> == NULL) 229{ 230 list_<label>=ctx->vectors->newVector(ctx->vectors); 231} 232{ 233 RETURN_TYPE_<label> * tcopy; 234 235 tcopy = (RETURN_TYPE_<label> *)ANTLR3_MALLOC(sizeof(RETURN_TYPE_<label>)); /* Note no memory allocation checks! */ 236 ANTLR3_MEMCPY((void *)(tcopy), (const void *)&<label>, sizeof(RETURN_TYPE_<label>)); 237 list_<label>->add(list_<label>, (void *)tcopy, freeScope); /* Add whatever the return type is */<\n> 238} 239>> 240 241// R e w r i t e 242 243rewriteCode( 244 alts, 245 description, 246 referencedElementsDeep, // ALL referenced elements to right of -> 247 referencedTokenLabels, 248 referencedTokenListLabels, 249 referencedRuleLabels, 250 referencedRuleListLabels, 251 referencedWildcardLabels, 252 referencedWildcardListLabels, 253 rewriteBlockLevel, 254 enclosingTreeLevel, 255 treeLevel) ::= 256<< 257 258/* AST REWRITE 259 * elements : <referencedElementsDeep; separator=", "> 260 * token labels : <referencedTokenLabels; separator=", "> 261 * rule labels : <referencedRuleLabels; separator=", "> 262 * token list labels : <referencedTokenListLabels; separator=", "> 263 * rule list labels : <referencedRuleListLabels; separator=", "> 264 */ 265<if(backtracking)> 266if ( <actions.(actionScope).synpredgate> ) <\n> 267<endif> 268{ 269 <rewriteCodeLabelsDecl()> 270 <rewriteCodeLabelsInit()> 271 root_0 = (<ASTLabelType>)(ADAPTOR->nilNode(ADAPTOR)); 272 <prevRuleRootRef()>.tree = root_0; 273 <alts:rewriteAlt(); separator="else "> 274 <if(TREE_PARSER)> 275 <if(rewriteMode)> 276 <prevRuleRootRef()>.tree = (<ASTLabelType>)(ADAPTOR->rulePostProcessing(ADAPTOR, root_0)); 277 INPUT->replaceChildren(INPUT, ADAPTOR->getParent(ADAPTOR, retval.start), 278 ADAPTOR->getChildIndex(ADAPTOR, retval.start), 279 ADAPTOR->getChildIndex(ADAPTOR, _last), 280 retval.tree); 281 <endif> 282 <endif> 283 <prevRuleRootRef()>.tree = root_0; // set result root 284 <rewriteCodeLabelsFree()> 285 286} 287>> 288 289rewriteCodeLabelsDecl() ::= << 290<referencedTokenLabels 291 :{it | pANTLR3_REWRITE_RULE_<rewriteElementType>_STREAM stream_<it>;}; 292 separator="\n" 293> 294<referencedTokenListLabels 295 :{it | pANTLR3_REWRITE_RULE_<rewriteElementType>_STREAM stream_<it>;}; 296 separator="\n" 297> 298<referencedRuleLabels 299 :{it | pANTLR3_REWRITE_RULE_SUBTREE_STREAM stream_<it>;}; 300 separator="\n" 301> 302<referencedRuleListLabels 303 :{it | pANTLR3_REWRITE_RULE_SUBTREE_STREAM stream_<it>;}; 304 separator="\n" 305> 306>> 307 308rewriteCodeLabelsInit() ::= << 309<referencedTokenLabels 310:{it | stream_<it>=antlr3RewriteRule<rewriteElementType>StreamNewAEE(ADAPTOR, RECOGNIZER, (pANTLR3_UINT8)"token <it>", <it>);}; 311separator="\n" 312> 313<referencedTokenListLabels 314:{it | stream_<it>=antlr3RewriteRule<rewriteElementType>StreamNewAEV(ADAPTOR, RECOGNIZER, (pANTLR3_UINT8)"token <it>", list_<it>); }; 315separator="\n" 316> 317<referencedRuleLabels 318:{it | stream_<it>=antlr3RewriteRuleSubtreeStreamNewAEE(ADAPTOR, RECOGNIZER, (pANTLR3_UINT8)"token <it>", <it>.tree != NULL ? <it>.tree : NULL);}; 319separator="\n" 320> 321<referencedRuleListLabels 322:{it | stream_<it>=antlr3RewriteRuleSubtreeStreamNewAEV(ADAPTOR, RECOGNIZER, (pANTLR3_UINT8)"token <it>", list_<it>);}; 323separator="\n" 324> 325>> 326rewriteCodeLabelsFree() ::= << 327<referencedTokenLabels 328:{it | if (stream_<it> != NULL) stream_<it>->free(stream_<it>); }; 329separator="\n" 330> 331<referencedTokenListLabels 332:{it | if (stream_<it> != NULL) stream_<it>->free(stream_<it>);}; 333separator="\n" 334> 335<referencedRuleLabels 336:{it | if (stream_<it> != NULL) stream_<it>->free(stream_<it>);}; 337separator="\n" 338> 339<referencedRuleListLabels 340:{it | if (stream_<it> != NULL) stream_<it>->free(stream_<it>);}; 341separator="\n" 342> 343>> 344 345/** Generate code for an optional rewrite block; note it uses the deep ref'd element 346 * list rather shallow like other blocks. 347 */ 348rewriteOptionalBlock( 349 alt, 350 rewriteBlockLevel, 351 referencedElementsDeep, // all nested refs 352 referencedElements, // elements in immediately block; no nested blocks 353 description) ::= 354<< 355// <fileName>:<description> 356{ 357 if ( <referencedElementsDeep:{el | (stream_<el> != NULL && stream_<el>->hasNext(stream_<el>)) }; separator="|| "> ) 358 { 359 <alt> 360 } 361 <referencedElementsDeep:{el | if ( stream_<el> != NULL) stream_<el>->reset(stream_<el>);<\n>}> 362}<\n> 363>> 364 365rewriteClosureBlock( 366 alt, 367 rewriteBlockLevel, 368 referencedElementsDeep, // all nested refs 369 referencedElements, // elements in immediately block; no nested blocks 370 description) ::= 371<< 372// <fileName>:<description> 373{ 374 while ( <referencedElements:{el | (stream_<el> != NULL && stream_<el>->hasNext(stream_<el>)) }; separator="|| "> ) 375 { 376 <alt> 377 } 378 <referencedElements:{el | if (stream_<el> != NULL) stream_<el>->reset(stream_<el>);<\n>}> 379}<\n> 380>> 381RewriteEarlyExitException() ::= 382<< 383CONSTRUCTEX(); 384EXCEPTION->type = ANTLR3_REWRITE_EARLY_EXCEPTION; 385EXCEPTION->name = (void *)ANTLR3_REWRITE_EARLY_EXCEPTION_NAME; 386>> 387rewritePositiveClosureBlock( 388 alt, 389 rewriteBlockLevel, 390 referencedElementsDeep, // all nested refs 391 referencedElements, // elements in immediately block; no nested blocks 392 description) ::= 393<< 394if (<referencedElements:{el | (stream_<el> == NULL || !stream_<el>->hasNext(stream_<el>)) }; separator="|| "> ) 395{ 396 <RewriteEarlyExitException()> 397} 398else 399{ 400 while ( <referencedElements:{el | (stream_<el>->hasNext(stream_<el>)) }; separator="|| "> ) { 401 <alt> 402 } 403 <referencedElements:{el | stream_<el>->reset(stream_<el>);<\n>}> 404} 405>> 406 407rewriteAlt(a) ::= << 408// <a.description> 409<if(a.pred)> 410if (<a.pred>) 411{ 412 <a.alt> 413}<\n> 414<else> 415{ 416 <a.alt> 417}<\n> 418<endif> 419>> 420 421/** For empty rewrites: "r : ... -> ;" */ 422rewriteEmptyAlt() ::= "root_0 = NULL; /* \<-- rewriteEmptyAlt()) */" 423 424rewriteTree(root,children,description,enclosingTreeLevel,treeLevel) ::= << 425// <fileName>:<description> 426{ 427 <ASTLabelType> root_<treeLevel> = (<ASTLabelType>)(ADAPTOR->nilNode(ADAPTOR)); 428 <root:rewriteElement()> 429 <children:rewriteElement()> 430 ADAPTOR->addChild(ADAPTOR, root_<enclosingTreeLevel>, root_<treeLevel>); 431}<\n> 432>> 433 434rewriteElementList(elements) ::= "<elements:rewriteElement()>" 435 436rewriteElement(e) ::= << 437<@pregen()> 438<e.el> 439>> 440 441/** Gen ID or ID[args] */ 442rewriteTokenRef(token,elementIndex,terminalOptions,args) ::= << 443ADAPTOR->addChild(ADAPTOR, root_<treeLevel>, <createRewriteNodeFromElement(...)>);<\n> 444>> 445 446/** Gen $label ... where defined via label=ID */ 447rewriteTokenLabelRef(label,elementIndex) ::= << 448ADAPTOR->addChild(ADAPTOR, root_<treeLevel>, stream_<label> == NULL ? NULL : stream_<label>->nextNode(stream_<label>));<\n> 449>> 450 451/** Gen $label ... where defined via label+=ID */ 452rewriteTokenListLabelRef(label,elementIndex) ::= << 453ADAPTOR->addChild(ADAPTOR, root_<treeLevel>, stream_<label> == NULL ? NULL : stream_<label>->nextNode(stream_<label>));<\n> 454>> 455 456/** Gen ^($label ...) */ 457rewriteTokenLabelRefRoot(label,elementIndex) ::= << 458root_<treeLevel> = (<ASTLabelType>)(ADAPTOR->becomeRootToken(ADAPTOR, stream_<label> == NULL ? NULL : stream_<label>->nextToken(stream_<label>), root_<treeLevel>));<\n> 459>> 460 461/** Gen ^($label ...) where label+=... */ 462rewriteTokenListLabelRefRoot ::= rewriteTokenLabelRefRoot 463 464/** Gen ^(ID ...) or ^(ID[args] ...) */ 465rewriteTokenRefRoot(token,elementIndex,terminalOptions,args) ::= << 466root_<treeLevel> = (<ASTLabelType>)(ADAPTOR->becomeRoot(ADAPTOR, <createRewriteNodeFromElement(...)>, root_<treeLevel>));<\n> 467>> 468 469rewriteImaginaryTokenRef(args,token,terminalOptions,elementIndex) ::= << 470ADAPTOR->addChild(ADAPTOR, root_<treeLevel>, <createImaginaryNode(tokenType=token, ...)>);<\n> 471>> 472 473rewriteImaginaryTokenRefRoot(args,token,terminalOptions,elementIndex) ::= << 474root_<treeLevel> = (<ASTLabelType>)(ADAPTOR->becomeRoot(ADAPTOR, <createImaginaryNode(tokenType=token, ...)>, root_<treeLevel>));<\n> 475>> 476 477/** plain -> {foo} action */ 478rewriteAction(action) ::= << 479root_0 = <action>;<\n> 480>> 481 482/** What is the name of the previous value of this rule's root tree? This 483 * let's us refer to $rule to mean previous value. I am reusing the 484 * variable 'tree' sitting in retval struct to hold the value of root_0 right 485 * before I set it during rewrites. The assign will be to retval.tree. 486 */ 487prevRuleRootRef() ::= "retval" 488 489rewriteRuleRef(rule,dup) ::= << 490ADAPTOR->addChild(ADAPTOR, root_<treeLevel>, stream_<rule> == NULL ? NULL : stream_<rule>->nextTree(stream_<rule>));<\n> 491>> 492 493rewriteRuleRefRoot(rule,dup) ::= << 494root_<treeLevel> = (<ASTLabelType>)(ADAPTOR->becomeRoot(ADAPTOR, stream_<rule> == NULL ? NULL : stream_<rule>->nextNode(stream_<rule>), root_<treeLevel>));<\n> 495>> 496 497rewriteNodeAction(action) ::= << 498ADAPTOR->addChild(ADAPTOR, root_<treeLevel>, <action>);<\n> 499>> 500 501rewriteNodeActionRoot(action) ::= << 502root_<treeLevel> = (<ASLabelType>)(ADAPTOR->becomeRoot(ADAPTOR, <action>, root_<treeLevel>));<\n> 503>> 504 505/** Gen $ruleLabel ... where defined via ruleLabel=rule */ 506rewriteRuleLabelRef(label) ::= << 507ADAPTOR->addChild(ADAPTOR, root_<treeLevel>, stream_<label> == NULL ? NULL : stream_<label>->nextTree(stream_<label>));<\n> 508>> 509 510/** Gen $ruleLabel ... where defined via ruleLabel+=rule */ 511rewriteRuleListLabelRef(label) ::= << 512ADAPTOR->addChild(ADAPTOR, root_<treeLevel>, stream_<label> == NULL ? NULL : stream_<label>->nextTree(stream_<label>));<\n> 513>> 514 515/** Gen ^($ruleLabel ...) where ruleLabel=rule */ 516rewriteRuleLabelRefRoot(label) ::= << 517root_<treeLevel> = (<ASTLabelType>)(ADAPTOR->becomeRoot(ADAPTOR, stream_<label> == NULL ? NULL : stream_<label>->nextNode(stream_<label>), root_<treeLevel>));<\n> 518>> 519 520/** Gen ^($ruleLabel ...) where ruleLabel+=rule */ 521rewriteRuleListLabelRefRoot(label) ::= << 522root_<treeLevel> = (<ASTLabelType>)(ADAPTOR->becomeRoot((<ASTLabelType>)(stream_<label> == NULL ? NULL : stream_<label>->nextNode(stream_<label>), root_<treeLevel>));<\n> 523>> 524 525rewriteWildcardLabelRef(label) ::= << 526ADAPTOR->addChild(ADAPTOR, root_<treeLevel>, stream_<label> == NULL ? NULL : stream_<label>->nextTree(stream_<label>));<\n> 527>> 528 529createImaginaryNode(tokenType,terminalOptions,args) ::= << 530<if(terminalOptions.node)> 531<! new MethodNode(IDLabel, args) !> 532<terminalOptions.node>New(<tokenType><if(args)>, <args; separator=", "><endif>) 533<else> 534<if(args)> 535 536#if <length(args)> == 2 537 (<ASTLabelType>)ADAPTOR->createTypeTokenText(ADAPTOR, <tokenType>, TOKTEXT(<args; separator=", ">)) 538#else 539 (<ASTLabelType>)ADAPTOR->createTypeText(ADAPTOR, <tokenType>, (pANTLR3_UINT8)<args; separator=", ">) 540#endif 541 542<else> 543(<ASTLabelType>)ADAPTOR->createTypeText(ADAPTOR, <tokenType>, (pANTLR3_UINT8)"<tokenType>") 544<endif> 545<endif> 546>> 547 548createRewriteNodeFromElement(token,terminalOptions,args) ::= << 549<if(terminalOptions.node)> 550<terminalOptions.node>New(stream_<token>->nextToken(stream_<token>)<if(args)>, <args; separator=", "><endif>) 551<else> 552<if(args)> <! must create new node from old !> 553 554#if <length(args)> == 2 555ADAPTOR->createTypeTokenText(ADAPTOR, <token>->getType(<token>, TOKTEXT(<token>, <args; separator=", ">)) /* JIMI */ 556#else 557ADAPTOR->createTypeToken(ADAPTOR, <token>->getType(<token>, <token>, <args; separator=", ">) 558#endif 559 560<else> 561stream_<token> == NULL ? NULL : stream_<token>->nextNode(stream_<token>) 562<endif> 563<endif> 564>> 565