| /* |
| [The "BSD license"] |
| Copyright (c) 2005-2009 Jim Idle, Temporal Wave LLC |
| http://www.temporal-wave.com |
| http://www.linkedin.com/in/jimidle |
| |
| All rights reserved. |
| |
| Redistribution and use in source and binary forms, with or without |
| modification, are permitted provided that the following conditions |
| are met: |
| 1. Redistributions of source code must retain the above copyright |
| notice, this list of conditions and the following disclaimer. |
| 2. Redistributions in binary form must reproduce the above copyright |
| notice, this list of conditions and the following disclaimer in the |
| documentation and/or other materials provided with the distribution. |
| 3. The name of the author may not be used to endorse or promote products |
| derived from this software without specific prior written permission. |
| |
| THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
| IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
| OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
| IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
| INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
| NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
| THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| */ |
| /** Add an adaptor property that knows how to build trees */ |
| @headerFile.members() ::= << |
| /* @headerFile.members() */ |
| pANTLR3_BASE_TREE_ADAPTOR adaptor; |
| pANTLR3_VECTOR_FACTORY vectors; |
| /* End @headerFile.members() */ |
| >> |
| |
| /** Install the tree adaptor interface pointer and anything else that |
| * tree parsers and producers require. |
| */ |
| @genericParser.apifuncs() ::= << |
| <if(PARSER)> |
| ADAPTOR = ANTLR3_TREE_ADAPTORNew(instream->tstream->tokenSource->strFactory);<\n> |
| <endif> |
| ctx->vectors = antlr3VectorFactoryNew(0); |
| >> |
| |
| @genericParser.cleanup() ::= << |
| ctx->vectors->close(ctx->vectors); |
| <if(PARSER)> |
| /* We created the adaptor so we must free it |
| */ |
| ADAPTOR->free(ADAPTOR); |
| <endif> |
| >> |
| |
| @returnScope.ruleReturnMembers() ::= << |
| |
| <super.ASTLabelType()> tree; |
| |
| >> |
| |
| /** Add a variable to track rule's return AST */ |
| ruleDeclarations() ::= << |
| <super.ruleDeclarations()> |
| <ASTLabelType> root_0;<\n> |
| >> |
| |
| ruleInitializations() ::= << |
| <super.ruleInitializations()> |
| root_0 = NULL;<\n> |
| >> |
| |
| ruleLabelDefs() ::= << |
| <super.ruleLabelDefs()> |
| <ruleDescriptor.tokenLabels:{it | <ASTLabelType> <it.label.text>_tree;}; separator="\n"> |
| <ruleDescriptor.tokenListLabels:{it | <ASTLabelType> <it.label.text>_tree;}; separator="\n"> |
| <ruleDescriptor.allTokenRefsInAltsWithRewrites |
| :{it | pANTLR3_REWRITE_RULE_<rewriteElementType>_STREAM stream_<it>;}; separator="\n"> |
| <ruleDescriptor.allRuleRefsInAltsWithRewrites |
| :{it | pANTLR3_REWRITE_RULE_SUBTREE_STREAM stream_<it>;}; separator="\n"> |
| >> |
| |
| /* Note that we defer the actual creation of any rewrite streams we need here and just initialize |
| * them to NULL. This saves creating huge numbers of rewrite streams that cannot be used as only |
| * one alt will be taken in a rule, but we are declaring all the streams here. So we define |
| * a macro that conatins the create code, then use this macro later to check if the stream |
| * has been created yet. Checking for NULL is almost free in C. |
| */ |
| ruleLabelInitializations() ::= << |
| <super.ruleLabelInitializations()> |
| <ruleDescriptor.tokenLabels:{it | <it.label.text>_tree = NULL;}; separator="\n"> |
| <ruleDescriptor.tokenListLabels:{it | <it.label.text>_tree = NULL;}; separator="\n"> |
| |
| <ruleDescriptor.allTokenRefsInAltsWithRewrites |
| :{it | stream_<it> = NULL; |
| #define CREATE_stream_<it> if (stream_<it> == NULL) {stream_<it> = antlr3RewriteRule<rewriteElementType>StreamNewAE(ADAPTOR, RECOGNIZER, (pANTLR3_UINT8)"token <it>"); \} }; separator="\n"> |
| <ruleDescriptor.allRuleRefsInAltsWithRewrites |
| :{it | stream_<it> = NULL; |
| #define CREATE_stream_<it> if (stream_<it> == NULL) {stream_<it> = antlr3RewriteRuleSubtreeStreamNewAE(ADAPTOR, RECOGNIZER, (pANTLR3_UINT8)"rule <it>"); \}}; separator="\n"> |
| |
| <if(ruleDescriptor.hasMultipleReturnValues)> |
| retval.tree = NULL; |
| <endif> |
| >> |
| |
| |
| /** a rule label including default value */ |
| ruleLabelInitVal(label) ::= << |
| <super.ruleLabelInitVal(...)> |
| <label.label.text>.tree = NULL; |
| >> |
| |
| /** When doing auto AST construction, we must define some variables; |
| * These should be turned off if doing rewrites. This must be a "mode" |
| * as a rule could have both rewrite and AST within the same alternative |
| * block. |
| */ |
| @alt.declarations() ::= << |
| <if(autoAST)> |
| <if(outerAlt)> |
| <endif> |
| <endif> |
| >> |
| |
| @alt.initializations() ::= << |
| <if(autoAST)> |
| <if(outerAlt)> |
| <if(!rewriteMode)> |
| root_0 = (<ASTLabelType>)(ADAPTOR->nilNode(ADAPTOR));<\n> |
| <endif> |
| <endif> |
| <endif> |
| >> |
| |
| |
| // T r a c k i n g R u l e E l e m e n t s |
| // |
| /** ID but track it for use in a rewrite rule */ |
| tokenRefTrack(token,label,elementIndex,terminalOptions) ::= << |
| <tokenRefBang(...)> <! Track implies no auto AST construction!> |
| <if(backtracking)>if ( <actions.(actionScope).synpredgate> ) { <endif>CREATE_stream_<token>; stream_<token>->add(stream_<token>, <label>, NULL);<if(backtracking)> }<endif><\n> |
| >> |
| |
| /** ids+=ID and track it for use in a rewrite rule; adds to ids *and* |
| * to the tracking list stream_ID for use in the rewrite. |
| */ |
| tokenRefTrackAndListLabel(token,label,elementIndex,terminalOptions) ::= << |
| <tokenRefTrack(...)> |
| <listLabel(elem=label,...)> |
| >> |
| |
| /** ^(ID ...) track for rewrite */ |
| tokenRefRuleRootTrack(token,label,elementIndex,terminalOptions) ::= << |
| <tokenRefBang(...)> |
| <if(backtracking)>if ( <actions.(actionScope).synpredgate> ) {<endif>CREATE_stream_<token>; stream_<token>->add(stream_<token>, <label>, NULL);<if(backtracking)> }<endif><\n> |
| >> |
| |
| wildcardTrack(label,elementIndex) ::= << |
| <super.wildcard(...)> |
| >> |
| |
| /** rule when output=AST and tracking for rewrite */ |
| ruleRefTrack(rule,label,elementIndex,args,scope) ::= << |
| <super.ruleRef(...)> |
| <if(backtracking)>if ( <actions.(actionScope).synpredgate> ) { <endif>CREATE_stream_<rule.name>; stream_<rule.name>->add(stream_<rule.name>, <label>.tree, NULL);<if(backtracking)> }<endif> |
| >> |
| |
| /** x+=rule when output=AST and tracking for rewrite */ |
| ruleRefTrackAndListLabel(rule,label,elementIndex,args,scope) ::= << |
| <ruleRefTrack(...)> |
| <listLabelTrack(...)> |
| >> |
| |
| /** ^(rule ...) rewrite */ |
| ruleRefRuleRootTrack(rule,label,elementIndex,args,scope) ::= << |
| <ruleRefRuleRoot(...)> |
| <if(backtracking)>if ( <actions.(actionScope).synpredgate> ) { <endif>CREATE_stream_<rule.name>; stream_<rule.name>->add(stream_<rule.name>, <label>.tree, NULL);<if(backtracking)> }<endif> |
| >> |
| |
| /** ^(x+=rule ...) rewrite */ |
| ruleRefRuleRootTrackAndListLabel(rule,label,elementIndex,args,scope) ::= << |
| <ruleRefRuleRootTrack(...)> |
| <listLabelAST(...)> |
| >> |
| |
| |
| // RULE REF AST |
| |
| |
| |
| /** Match ^(label+=TOKEN ...) track for rewrite */ |
| tokenRefRuleRootTrackAndListLabel(token,label,elementIndex,terminalOptions) ::= << |
| <tokenRefRuleRootTrack(...)> |
| <listLabel(elem=label,...)> |
| >> |
| |
| |
| /* How to accumulate lists when we are doing rewrite tracking... |
| */ |
| listLabelTrack(label) ::= << |
| /* listLabelTrack(label) |
| */ |
| if (list_<label> == NULL) |
| { |
| list_<label>=ctx->vectors->newVector(ctx->vectors); |
| } |
| list_<label>->add(list_<label>, <label>.tree, NULL); |
| >> |
| |
| /* How to accumulate lists of rule outputs (only allowed with AST |
| * option but if the user is going to walk the tree, they will want |
| * all their custom elements from rule returns. |
| * |
| * Normally, we use inline structures (which the compiler lays down |
| * code to copy from heap allocations. However, here we want to accumulate copies |
| * of the returned structures because we are adding them to a list. This only makes sense if the |
| * grammar is not rewriting the tree as a tree rewrite only preserves the tree, not the object/structure |
| * returned from the rule. The rewrite will extract the tree pointer. However, if we are not going to |
| * do a tree re-write, then the user may wish to iterate the structures returned by the rule in |
| * action code and will expect the user defined returns[] elements to be available when they do this. |
| * Hence we cannot just preserve the tree that was returned. So, we must copy the local structure and provide |
| * a function that can free the allocated space. We cannot know how to free user allocated elements and |
| * presume that the user will know to do this using their own factories for the structures they allocate. |
| */ |
| listLabelAST(label) ::= << |
| if (list_<label> == NULL) |
| { |
| list_<label>=ctx->vectors->newVector(ctx->vectors); |
| } |
| { |
| RETURN_TYPE_<label> * tcopy; |
| |
| tcopy = (RETURN_TYPE_<label> *)ANTLR3_MALLOC(sizeof(RETURN_TYPE_<label>)); /* Note no memory allocation checks! */ |
| ANTLR3_MEMCPY((void *)(tcopy), (const void *)&<label>, sizeof(RETURN_TYPE_<label>)); |
| list_<label>->add(list_<label>, (void *)tcopy, freeScope); /* Add whatever the return type is */<\n> |
| } |
| >> |
| |
| // R e w r i t e |
| |
| rewriteCode( |
| alts, |
| description, |
| referencedElementsDeep, // ALL referenced elements to right of -> |
| referencedTokenLabels, |
| referencedTokenListLabels, |
| referencedRuleLabels, |
| referencedRuleListLabels, |
| referencedWildcardLabels, |
| referencedWildcardListLabels, |
| rewriteBlockLevel, |
| enclosingTreeLevel, |
| treeLevel) ::= |
| << |
| |
| /* AST REWRITE |
| * elements : <referencedElementsDeep; separator=", "> |
| * token labels : <referencedTokenLabels; separator=", "> |
| * rule labels : <referencedRuleLabels; separator=", "> |
| * token list labels : <referencedTokenListLabels; separator=", "> |
| * rule list labels : <referencedRuleListLabels; separator=", "> |
| */ |
| <if(backtracking)> |
| if ( <actions.(actionScope).synpredgate> ) <\n> |
| <endif> |
| { |
| <rewriteCodeLabelsDecl()> |
| <rewriteCodeLabelsInit()> |
| root_0 = (<ASTLabelType>)(ADAPTOR->nilNode(ADAPTOR)); |
| <prevRuleRootRef()>.tree = root_0; |
| <alts:rewriteAlt(); separator="else "> |
| <if(TREE_PARSER)> |
| <if(rewriteMode)> |
| <prevRuleRootRef()>.tree = (<ASTLabelType>)(ADAPTOR->rulePostProcessing(ADAPTOR, root_0)); |
| INPUT->replaceChildren(INPUT, ADAPTOR->getParent(ADAPTOR, retval.start), |
| ADAPTOR->getChildIndex(ADAPTOR, retval.start), |
| ADAPTOR->getChildIndex(ADAPTOR, _last), |
| retval.tree); |
| <endif> |
| <endif> |
| <prevRuleRootRef()>.tree = root_0; // set result root |
| <rewriteCodeLabelsFree()> |
| |
| } |
| >> |
| |
| rewriteCodeLabelsDecl() ::= << |
| <referencedTokenLabels |
| :{it | pANTLR3_REWRITE_RULE_<rewriteElementType>_STREAM stream_<it>;}; |
| separator="\n" |
| > |
| <referencedTokenListLabels |
| :{it | pANTLR3_REWRITE_RULE_<rewriteElementType>_STREAM stream_<it>;}; |
| separator="\n" |
| > |
| <referencedRuleLabels |
| :{it | pANTLR3_REWRITE_RULE_SUBTREE_STREAM stream_<it>;}; |
| separator="\n" |
| > |
| <referencedRuleListLabels |
| :{it | pANTLR3_REWRITE_RULE_SUBTREE_STREAM stream_<it>;}; |
| separator="\n" |
| > |
| >> |
| |
| rewriteCodeLabelsInit() ::= << |
| <referencedTokenLabels |
| :{it | stream_<it>=antlr3RewriteRule<rewriteElementType>StreamNewAEE(ADAPTOR, RECOGNIZER, (pANTLR3_UINT8)"token <it>", <it>);}; |
| separator="\n" |
| > |
| <referencedTokenListLabels |
| :{it | stream_<it>=antlr3RewriteRule<rewriteElementType>StreamNewAEV(ADAPTOR, RECOGNIZER, (pANTLR3_UINT8)"token <it>", list_<it>); }; |
| separator="\n" |
| > |
| <referencedRuleLabels |
| :{it | stream_<it>=antlr3RewriteRuleSubtreeStreamNewAEE(ADAPTOR, RECOGNIZER, (pANTLR3_UINT8)"token <it>", <it>.tree != NULL ? <it>.tree : NULL);}; |
| separator="\n" |
| > |
| <referencedRuleListLabels |
| :{it | stream_<it>=antlr3RewriteRuleSubtreeStreamNewAEV(ADAPTOR, RECOGNIZER, (pANTLR3_UINT8)"token <it>", list_<it>);}; |
| separator="\n" |
| > |
| >> |
| rewriteCodeLabelsFree() ::= << |
| <referencedTokenLabels |
| :{it | if (stream_<it> != NULL) stream_<it>->free(stream_<it>); }; |
| separator="\n" |
| > |
| <referencedTokenListLabels |
| :{it | if (stream_<it> != NULL) stream_<it>->free(stream_<it>);}; |
| separator="\n" |
| > |
| <referencedRuleLabels |
| :{it | if (stream_<it> != NULL) stream_<it>->free(stream_<it>);}; |
| separator="\n" |
| > |
| <referencedRuleListLabels |
| :{it | if (stream_<it> != NULL) stream_<it>->free(stream_<it>);}; |
| separator="\n" |
| > |
| >> |
| |
| /** Generate code for an optional rewrite block; note it uses the deep ref'd element |
| * list rather shallow like other blocks. |
| */ |
| rewriteOptionalBlock( |
| alt, |
| rewriteBlockLevel, |
| referencedElementsDeep, // all nested refs |
| referencedElements, // elements in immediately block; no nested blocks |
| description) ::= |
| << |
| // <fileName>:<description> |
| { |
| if ( <referencedElementsDeep:{el | (stream_<el> != NULL && stream_<el>->hasNext(stream_<el>)) }; separator="|| "> ) |
| { |
| <alt> |
| } |
| <referencedElementsDeep:{el | if ( stream_<el> != NULL) stream_<el>->reset(stream_<el>);<\n>}> |
| }<\n> |
| >> |
| |
| rewriteClosureBlock( |
| alt, |
| rewriteBlockLevel, |
| referencedElementsDeep, // all nested refs |
| referencedElements, // elements in immediately block; no nested blocks |
| description) ::= |
| << |
| // <fileName>:<description> |
| { |
| while ( <referencedElements:{el | (stream_<el> != NULL && stream_<el>->hasNext(stream_<el>)) }; separator="|| "> ) |
| { |
| <alt> |
| } |
| <referencedElements:{el | if (stream_<el> != NULL) stream_<el>->reset(stream_<el>);<\n>}> |
| }<\n> |
| >> |
| RewriteEarlyExitException() ::= |
| << |
| CONSTRUCTEX(); |
| EXCEPTION->type = ANTLR3_REWRITE_EARLY_EXCEPTION; |
| EXCEPTION->name = (void *)ANTLR3_REWRITE_EARLY_EXCEPTION_NAME; |
| >> |
| rewritePositiveClosureBlock( |
| alt, |
| rewriteBlockLevel, |
| referencedElementsDeep, // all nested refs |
| referencedElements, // elements in immediately block; no nested blocks |
| description) ::= |
| << |
| if (<referencedElements:{el | (stream_<el> == NULL || !stream_<el>->hasNext(stream_<el>)) }; separator="|| "> ) |
| { |
| <RewriteEarlyExitException()> |
| } |
| else |
| { |
| while ( <referencedElements:{el | (stream_<el>->hasNext(stream_<el>)) }; separator="|| "> ) { |
| <alt> |
| } |
| <referencedElements:{el | stream_<el>->reset(stream_<el>);<\n>}> |
| } |
| >> |
| |
| rewriteAlt(a) ::= << |
| // <a.description> |
| <if(a.pred)> |
| if (<a.pred>) |
| { |
| <a.alt> |
| }<\n> |
| <else> |
| { |
| <a.alt> |
| }<\n> |
| <endif> |
| >> |
| |
| /** For empty rewrites: "r : ... -> ;" */ |
| rewriteEmptyAlt() ::= "root_0 = NULL; /* \<-- rewriteEmptyAlt()) */" |
| |
| rewriteTree(root,children,description,enclosingTreeLevel,treeLevel) ::= << |
| // <fileName>:<description> |
| { |
| <ASTLabelType> root_<treeLevel> = (<ASTLabelType>)(ADAPTOR->nilNode(ADAPTOR)); |
| <root:rewriteElement()> |
| <children:rewriteElement()> |
| ADAPTOR->addChild(ADAPTOR, root_<enclosingTreeLevel>, root_<treeLevel>); |
| }<\n> |
| >> |
| |
| rewriteElementList(elements) ::= "<elements:rewriteElement()>" |
| |
| rewriteElement(e) ::= << |
| <@pregen()> |
| <e.el> |
| >> |
| |
| /** Gen ID or ID[args] */ |
| rewriteTokenRef(token,elementIndex,terminalOptions,args) ::= << |
| ADAPTOR->addChild(ADAPTOR, root_<treeLevel>, <createRewriteNodeFromElement(...)>);<\n> |
| >> |
| |
| /** Gen $label ... where defined via label=ID */ |
| rewriteTokenLabelRef(label,elementIndex) ::= << |
| ADAPTOR->addChild(ADAPTOR, root_<treeLevel>, stream_<label> == NULL ? NULL : stream_<label>->nextNode(stream_<label>));<\n> |
| >> |
| |
| /** Gen $label ... where defined via label+=ID */ |
| rewriteTokenListLabelRef(label,elementIndex) ::= << |
| ADAPTOR->addChild(ADAPTOR, root_<treeLevel>, stream_<label> == NULL ? NULL : stream_<label>->nextNode(stream_<label>));<\n> |
| >> |
| |
| /** Gen ^($label ...) */ |
| rewriteTokenLabelRefRoot(label,elementIndex) ::= << |
| root_<treeLevel> = (<ASTLabelType>)(ADAPTOR->becomeRootToken(ADAPTOR, stream_<label> == NULL ? NULL : stream_<label>->nextToken(stream_<label>), root_<treeLevel>));<\n> |
| >> |
| |
| /** Gen ^($label ...) where label+=... */ |
| rewriteTokenListLabelRefRoot ::= rewriteTokenLabelRefRoot |
| |
| /** Gen ^(ID ...) or ^(ID[args] ...) */ |
| rewriteTokenRefRoot(token,elementIndex,terminalOptions,args) ::= << |
| root_<treeLevel> = (<ASTLabelType>)(ADAPTOR->becomeRoot(ADAPTOR, <createRewriteNodeFromElement(...)>, root_<treeLevel>));<\n> |
| >> |
| |
| rewriteImaginaryTokenRef(args,token,terminalOptions,elementIndex) ::= << |
| ADAPTOR->addChild(ADAPTOR, root_<treeLevel>, <createImaginaryNode(tokenType=token, ...)>);<\n> |
| >> |
| |
| rewriteImaginaryTokenRefRoot(args,token,terminalOptions,elementIndex) ::= << |
| root_<treeLevel> = (<ASTLabelType>)(ADAPTOR->becomeRoot(ADAPTOR, <createImaginaryNode(tokenType=token, ...)>, root_<treeLevel>));<\n> |
| >> |
| |
| /** plain -> {foo} action */ |
| rewriteAction(action) ::= << |
| root_0 = <action>;<\n> |
| >> |
| |
| /** What is the name of the previous value of this rule's root tree? This |
| * let's us refer to $rule to mean previous value. I am reusing the |
| * variable 'tree' sitting in retval struct to hold the value of root_0 right |
| * before I set it during rewrites. The assign will be to retval.tree. |
| */ |
| prevRuleRootRef() ::= "retval" |
| |
| rewriteRuleRef(rule,dup) ::= << |
| ADAPTOR->addChild(ADAPTOR, root_<treeLevel>, stream_<rule> == NULL ? NULL : stream_<rule>->nextTree(stream_<rule>));<\n> |
| >> |
| |
| rewriteRuleRefRoot(rule,dup) ::= << |
| root_<treeLevel> = (<ASTLabelType>)(ADAPTOR->becomeRoot(ADAPTOR, stream_<rule> == NULL ? NULL : stream_<rule>->nextNode(stream_<rule>), root_<treeLevel>));<\n> |
| >> |
| |
| rewriteNodeAction(action) ::= << |
| ADAPTOR->addChild(ADAPTOR, root_<treeLevel>, <action>);<\n> |
| >> |
| |
| rewriteNodeActionRoot(action) ::= << |
| root_<treeLevel> = (<ASLabelType>)(ADAPTOR->becomeRoot(ADAPTOR, <action>, root_<treeLevel>));<\n> |
| >> |
| |
| /** Gen $ruleLabel ... where defined via ruleLabel=rule */ |
| rewriteRuleLabelRef(label) ::= << |
| ADAPTOR->addChild(ADAPTOR, root_<treeLevel>, stream_<label> == NULL ? NULL : stream_<label>->nextTree(stream_<label>));<\n> |
| >> |
| |
| /** Gen $ruleLabel ... where defined via ruleLabel+=rule */ |
| rewriteRuleListLabelRef(label) ::= << |
| ADAPTOR->addChild(ADAPTOR, root_<treeLevel>, stream_<label> == NULL ? NULL : stream_<label>->nextTree(stream_<label>));<\n> |
| >> |
| |
| /** Gen ^($ruleLabel ...) where ruleLabel=rule */ |
| rewriteRuleLabelRefRoot(label) ::= << |
| root_<treeLevel> = (<ASTLabelType>)(ADAPTOR->becomeRoot(ADAPTOR, stream_<label> == NULL ? NULL : stream_<label>->nextNode(stream_<label>), root_<treeLevel>));<\n> |
| >> |
| |
| /** Gen ^($ruleLabel ...) where ruleLabel+=rule */ |
| rewriteRuleListLabelRefRoot(label) ::= << |
| root_<treeLevel> = (<ASTLabelType>)(ADAPTOR->becomeRoot((<ASTLabelType>)(stream_<label> == NULL ? NULL : stream_<label>->nextNode(stream_<label>), root_<treeLevel>));<\n> |
| >> |
| |
| rewriteWildcardLabelRef(label) ::= << |
| ADAPTOR->addChild(ADAPTOR, root_<treeLevel>, stream_<label> == NULL ? NULL : stream_<label>->nextTree(stream_<label>));<\n> |
| >> |
| |
| createImaginaryNode(tokenType,terminalOptions,args) ::= << |
| <if(terminalOptions.node)> |
| <! new MethodNode(IDLabel, args) !> |
| <terminalOptions.node>New(<tokenType><if(args)>, <args; separator=", "><endif>) |
| <else> |
| <if(args)> |
| |
| #if <length(args)> == 2 |
| (<ASTLabelType>)ADAPTOR->createTypeTokenText(ADAPTOR, <tokenType>, TOKTEXT(<args; separator=", ">)) |
| #else |
| (<ASTLabelType>)ADAPTOR->createTypeText(ADAPTOR, <tokenType>, (pANTLR3_UINT8)<args; separator=", ">) |
| #endif |
| |
| <else> |
| (<ASTLabelType>)ADAPTOR->createTypeText(ADAPTOR, <tokenType>, (pANTLR3_UINT8)"<tokenType>") |
| <endif> |
| <endif> |
| >> |
| |
| createRewriteNodeFromElement(token,terminalOptions,args) ::= << |
| <if(terminalOptions.node)> |
| <terminalOptions.node>New(stream_<token>->nextToken(stream_<token>)<if(args)>, <args; separator=", "><endif>) |
| <else> |
| <if(args)> <! must create new node from old !> |
| |
| #if <length(args)> == 2 |
| ADAPTOR->createTypeTokenText(ADAPTOR, <token>->getType(<token>, TOKTEXT(<token>, <args; separator=", ">)) /* JIMI */ |
| #else |
| ADAPTOR->createTypeToken(ADAPTOR, <token>->getType(<token>, <token>, <args; separator=", ">) |
| #endif |
| |
| <else> |
| stream_<token> == NULL ? NULL : stream_<token>->nextNode(stream_<token>) |
| <endif> |
| <endif> |
| >> |