Home | History | Annotate | Download | only in C
      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() */
     34 pANTLR3_BASE_TREE_ADAPTOR	adaptor;
     35 pANTLR3_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)>
     44 ADAPTOR	= ANTLR3_TREE_ADAPTORNew(instream->tstream->tokenSource->strFactory);<\n>
     45 <endif>
     46 ctx->vectors	= antlr3VectorFactoryNew(0);
     47 >>
     48 
     49 @genericParser.cleanup() ::= <<
     50 ctx->vectors->close(ctx->vectors);
     51 <if(PARSER)>
     52 /* We created the adaptor so we must free it
     53  */
     54 ADAPTOR->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 */
     65 ruleDeclarations() ::= <<
     66 <super.ruleDeclarations()>
     67 <ASTLabelType> root_0;<\n>
     68 >>
     69 
     70 ruleInitializations() ::= <<
     71 <super.ruleInitializations()>
     72 root_0 = NULL;<\n>
     73 >>
     74 
     75 ruleLabelDefs() ::= <<
     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  */
     91 ruleLabelInitializations() ::= <<
     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)>
    104 retval.tree  = NULL;
    105 <endif>
    106 >>
    107 
    108 
    109 /**  a rule label including default value */
    110 ruleLabelInitVal(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)>
    131 root_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 */
    141 tokenRefTrack(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  */
    149 tokenRefTrackAndListLabel(token,label,elementIndex,terminalOptions) ::= <<
    150 <tokenRefTrack(...)>
    151 <listLabel(elem=label,...)>
    152 >>
    153 
    154 /** ^(ID ...) track for rewrite */
    155 tokenRefRuleRootTrack(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 
    160 wildcardTrack(label,elementIndex) ::= <<
    161 <super.wildcard(...)>
    162 >>
    163 
    164 /** rule when output=AST and tracking for rewrite */
    165 ruleRefTrack(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 */
    171 ruleRefTrackAndListLabel(rule,label,elementIndex,args,scope) ::= <<
    172 <ruleRefTrack(...)>
    173 <listLabelTrack(...)>
    174 >>
    175 
    176 /** ^(rule ...) rewrite */
    177 ruleRefRuleRootTrack(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 */
    183 ruleRefRuleRootTrackAndListLabel(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 */
    194 tokenRefRuleRootTrackAndListLabel(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  */
    202 listLabelTrack(label) ::= <<
    203 /* listLabelTrack(label)
    204  */
    205 if (list_<label> == NULL)
    206 {
    207     list_<label>=ctx->vectors->newVector(ctx->vectors);
    208 }
    209 list_<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  */
    227 listLabelAST(label) ::= <<
    228 if (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 
    243 rewriteCode(
    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)>
    266 if ( <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 
    289 rewriteCodeLabelsDecl() ::= <<
    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 
    308 rewriteCodeLabelsInit() ::= <<
    309 <referencedTokenLabels
    310 :{it | stream_<it>=antlr3RewriteRule<rewriteElementType>StreamNewAEE(ADAPTOR,  RECOGNIZER, (pANTLR3_UINT8)"token <it>", <it>);};
    311 separator="\n"
    312 >
    313 <referencedTokenListLabels
    314 :{it | stream_<it>=antlr3RewriteRule<rewriteElementType>StreamNewAEV(ADAPTOR,  RECOGNIZER, (pANTLR3_UINT8)"token <it>", list_<it>); };
    315 separator="\n"
    316 >
    317 <referencedRuleLabels
    318 :{it | stream_<it>=antlr3RewriteRuleSubtreeStreamNewAEE(ADAPTOR,  RECOGNIZER, (pANTLR3_UINT8)"token <it>", <it>.tree != NULL ? <it>.tree : NULL);};
    319 separator="\n"
    320 >
    321 <referencedRuleListLabels
    322 :{it | stream_<it>=antlr3RewriteRuleSubtreeStreamNewAEV(ADAPTOR,  RECOGNIZER, (pANTLR3_UINT8)"token <it>", list_<it>);};
    323 separator="\n"
    324 >
    325 >>
    326 rewriteCodeLabelsFree() ::= <<
    327 <referencedTokenLabels
    328 :{it | if (stream_<it> != NULL) stream_<it>->free(stream_<it>); };
    329 separator="\n"
    330 >
    331 <referencedTokenListLabels
    332 :{it | if (stream_<it> != NULL) stream_<it>->free(stream_<it>);};
    333 separator="\n"
    334 >
    335 <referencedRuleLabels
    336 :{it | if (stream_<it> != NULL) stream_<it>->free(stream_<it>);};
    337 separator="\n"
    338 >
    339 <referencedRuleListLabels
    340 :{it | if (stream_<it> != NULL) stream_<it>->free(stream_<it>);};
    341 separator="\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   */
    348 rewriteOptionalBlock(
    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 
    365 rewriteClosureBlock(
    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 >>
    381 RewriteEarlyExitException() ::=
    382 <<
    383 CONSTRUCTEX();
    384 EXCEPTION->type         = ANTLR3_REWRITE_EARLY_EXCEPTION;
    385 EXCEPTION->name         = (void *)ANTLR3_REWRITE_EARLY_EXCEPTION_NAME;
    386 >>
    387 rewritePositiveClosureBlock(
    388 	alt,
    389 	rewriteBlockLevel,
    390 	referencedElementsDeep, // all nested refs
    391 	referencedElements,		// elements in immediately block; no nested blocks
    392 	description) ::=
    393 <<
    394 if (<referencedElements:{el | (stream_<el> == NULL || !stream_<el>->hasNext(stream_<el>)) }; separator="|| "> )
    395 {
    396     <RewriteEarlyExitException()>
    397 }
    398 else
    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 
    407 rewriteAlt(a) ::= <<
    408 // <a.description>
    409 <if(a.pred)>
    410 if (<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 : ... -> ;" */
    422 rewriteEmptyAlt() ::= "root_0 = NULL; /* \<-- rewriteEmptyAlt()) */"
    423 
    424 rewriteTree(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 
    434 rewriteElementList(elements) ::= "<elements:rewriteElement()>"
    435 
    436 rewriteElement(e) ::= <<
    437 <@pregen()>
    438 <e.el>
    439 >>
    440 
    441 /** Gen ID or ID[args] */
    442 rewriteTokenRef(token,elementIndex,terminalOptions,args) ::= <<
    443 ADAPTOR->addChild(ADAPTOR, root_<treeLevel>, <createRewriteNodeFromElement(...)>);<\n>
    444 >>
    445 
    446 /** Gen $label ... where defined via label=ID */
    447 rewriteTokenLabelRef(label,elementIndex) ::= <<
    448 ADAPTOR->addChild(ADAPTOR, root_<treeLevel>, stream_<label> == NULL ? NULL : stream_<label>->nextNode(stream_<label>));<\n>
    449 >>
    450 
    451 /** Gen $label ... where defined via label+=ID */
    452 rewriteTokenListLabelRef(label,elementIndex) ::= <<
    453 ADAPTOR->addChild(ADAPTOR, root_<treeLevel>, stream_<label> == NULL ? NULL : stream_<label>->nextNode(stream_<label>));<\n>
    454 >>
    455 
    456 /** Gen ^($label ...) */
    457 rewriteTokenLabelRefRoot(label,elementIndex) ::= <<
    458 root_<treeLevel> = (<ASTLabelType>)(ADAPTOR->becomeRootToken(ADAPTOR, stream_<label> == NULL ? NULL : stream_<label>->nextToken(stream_<label>), root_<treeLevel>));<\n>
    459 >>
    460 
    461 /** Gen ^($label ...) where label+=... */
    462 rewriteTokenListLabelRefRoot ::= rewriteTokenLabelRefRoot
    463 
    464 /** Gen ^(ID ...) or ^(ID[args] ...) */
    465 rewriteTokenRefRoot(token,elementIndex,terminalOptions,args) ::= <<
    466 root_<treeLevel> = (<ASTLabelType>)(ADAPTOR->becomeRoot(ADAPTOR, <createRewriteNodeFromElement(...)>, root_<treeLevel>));<\n>
    467 >>
    468 
    469 rewriteImaginaryTokenRef(args,token,terminalOptions,elementIndex) ::= <<
    470 ADAPTOR->addChild(ADAPTOR, root_<treeLevel>, <createImaginaryNode(tokenType=token, ...)>);<\n>
    471 >>
    472 
    473 rewriteImaginaryTokenRefRoot(args,token,terminalOptions,elementIndex) ::= <<
    474 root_<treeLevel> = (<ASTLabelType>)(ADAPTOR->becomeRoot(ADAPTOR, <createImaginaryNode(tokenType=token, ...)>, root_<treeLevel>));<\n>
    475 >>
    476 
    477 /** plain -> {foo} action */
    478 rewriteAction(action) ::= <<
    479 root_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  */
    487 prevRuleRootRef() ::= "retval"
    488 
    489 rewriteRuleRef(rule,dup) ::= <<
    490 ADAPTOR->addChild(ADAPTOR, root_<treeLevel>, stream_<rule> == NULL ? NULL : stream_<rule>->nextTree(stream_<rule>));<\n>
    491 >>
    492 
    493 rewriteRuleRefRoot(rule,dup) ::= <<
    494 root_<treeLevel> = (<ASTLabelType>)(ADAPTOR->becomeRoot(ADAPTOR, stream_<rule> == NULL ? NULL : stream_<rule>->nextNode(stream_<rule>), root_<treeLevel>));<\n>
    495 >>
    496 
    497 rewriteNodeAction(action) ::= <<
    498 ADAPTOR->addChild(ADAPTOR, root_<treeLevel>, <action>);<\n>
    499 >>
    500 
    501 rewriteNodeActionRoot(action) ::= <<
    502 root_<treeLevel> = (<ASLabelType>)(ADAPTOR->becomeRoot(ADAPTOR, <action>, root_<treeLevel>));<\n>
    503 >>
    504 
    505 /** Gen $ruleLabel ... where defined via ruleLabel=rule */
    506 rewriteRuleLabelRef(label) ::= <<
    507 ADAPTOR->addChild(ADAPTOR, root_<treeLevel>, stream_<label> == NULL ? NULL : stream_<label>->nextTree(stream_<label>));<\n>
    508 >>
    509 
    510 /** Gen $ruleLabel ... where defined via ruleLabel+=rule */
    511 rewriteRuleListLabelRef(label) ::= <<
    512 ADAPTOR->addChild(ADAPTOR, root_<treeLevel>, stream_<label> == NULL ? NULL : stream_<label>->nextTree(stream_<label>));<\n>
    513 >>
    514 
    515 /** Gen ^($ruleLabel ...) where ruleLabel=rule */
    516 rewriteRuleLabelRefRoot(label) ::= <<
    517 root_<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 */
    521 rewriteRuleListLabelRefRoot(label) ::= <<
    522 root_<treeLevel> = (<ASTLabelType>)(ADAPTOR->becomeRoot((<ASTLabelType>)(stream_<label> == NULL ? NULL : stream_<label>->nextNode(stream_<label>), root_<treeLevel>));<\n>
    523 >>
    524 
    525 rewriteWildcardLabelRef(label) ::= <<
    526 ADAPTOR->addChild(ADAPTOR, root_<treeLevel>, stream_<label> == NULL ? NULL : stream_<label>->nextTree(stream_<label>));<\n>
    527 >>
    528 
    529 createImaginaryNode(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 
    548 createRewriteNodeFromElement(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
    555 ADAPTOR->createTypeTokenText(ADAPTOR, <token>->getType(<token>, TOKTEXT(<token>, <args; separator=", ">)) /* JIMI */
    556 #else
    557 ADAPTOR->createTypeToken(ADAPTOR, <token>->getType(<token>, <token>, <args; separator=", ">)
    558 #endif
    559 
    560 <else>
    561 stream_<token> == NULL ? NULL : stream_<token>->nextNode(stream_<token>)
    562 <endif>
    563 <endif>
    564 >>
    565