| /* |
| [The "BSD license"] |
| Copyright (c) 2006, 2007 Kay Roepke 2010 Alan Condit |
| 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. |
| */ |
| @genericParserHeaderFile.memVars() ::= << |
| /* AST parserHeaderFile.memVars */ |
| NSInteger ruleLevel; |
| NSArray *ruleNames; |
| <@super.memVars()> /* AST super.memVars */ |
| <parserMemVars()> /* AST parserMemVars */ |
| >> |
| |
| @genericParserHeaderFile.properties() ::= << |
| /* AST parserHeaderFile.properties */ |
| <@super.properties()> /* AST super.properties */ |
| <parserProperties()> /* AST parserproperties */ |
| >> |
| |
| @genericParserHeaderFile.methodsDecl() ::= << |
| /* AST parserHeaderFile.methodsDecl */ |
| <@super.methodsDecl()> /* AST super.methodsDecl */ |
| <parserMethodsDecl()> /* AST parsermethodsDecl */ |
| >> |
| |
| @genericParser.synthesize() ::= << |
| /* AST genericParser.synthesize */ |
| <@super.synthesize()> |
| <parserSynthesize()> |
| >> |
| |
| @genericParser.methods() ::= << |
| /* AST genericParser.methods */ |
| <@super.methods()> |
| <parserMethods()> |
| >> |
| |
| /* additional init code for tree support */ |
| @genericParser.init() ::= << |
| /* AST genericParser.init */ |
| <@super.init()> |
| [self setTreeAdaptor:[[ANTLRCommonTreeAdaptor newTreeAdaptor] retain]]; |
| >> |
| |
| @genericParser.dealloc() ::= << |
| /* AST genericParser.dealloc */ |
| [self setTreeAdaptor:nil]; |
| <@super.dealloc()> |
| >> |
| |
| /* Add an adaptor property that knows how to build trees */ |
| parserMemVars() ::= << |
| /* AST parserMemVars */ |
| id\<ANTLRTreeAdaptor> treeAdaptor; |
| >> |
| |
| /* Add an adaptor property that knows how to build trees */ |
| parserProperties() ::= << |
| /* AST parserProperties */ |
| @property (retain, getter=getTreeAdaptor, setter=setTreeAdaptor:) id\<ANTLRTreeAdaptor> treeAdaptor; |
| >> |
| |
| /** Declaration of additional tree support methods - go in interface of parserHeaderFile() */ |
| parserMethodsDecl() ::= << |
| /* AST parserMethodsDecl */ |
| - (id\<ANTLRTreeAdaptor>) getTreeAdaptor; |
| - (void) setTreeAdaptor:(id\<ANTLRTreeAdaptor>)theTreeAdaptor; |
| >> |
| |
| /* Add an adaptor property that knows how to build trees */ |
| parserSynthesize() ::= << |
| /* AST parserProperties */ |
| @synthesize treeAdaptor; |
| >> |
| |
| /** Definition of addition tree support methods - go in implementation of genericParser() */ |
| parserMethods() ::= << |
| /* AST parserMethods */ |
| - (id\<ANTLRTreeAdaptor>) getTreeAdaptor |
| { |
| return treeAdaptor; |
| } |
| |
| - (void) setTreeAdaptor:(id\<ANTLRTreeAdaptor>)aTreeAdaptor |
| { |
| if (aTreeAdaptor != treeAdaptor) { |
| treeAdaptor = aTreeAdaptor; |
| } |
| } |
| >> |
| |
| /** addition memVars for returnscopes */ |
| @returnScopeInterface.memVars() ::= << |
| /* AST returnScopeInterface.memVars */ |
| <recognizer.ASTLabelType; null="ANTLRCommonTree"> *tree; |
| >> |
| |
| /** the interface of returnScope properties */ |
| @returnScopeInterface.properties() ::= << |
| /* AST returnScopeInterface.properties */ |
| @property (retain, getter=getTree, setter=setTree:) <recognizer.ASTLabelType; null="ANTLRCommonTree"> *tree; |
| >> |
| |
| /** the interface of returnScope methodsDecl */ |
| @returnScopeInterface.methodsDecl() ::= << |
| /* AST returnScopeInterface.methodsDecl */ |
| - (<recognizer.ASTLabelType; null="ANTLRCommonTree"> *)getTree;<\n> |
| - (void) setTree:(<recognizer.ASTLabelType; null="ANTLRCommonTree"> *)aTree;<\n> |
| >> |
| |
| /** the implementation of returnScope synthesize */ |
| @returnScopeImplementation.synthesize() ::= << |
| /* AST returnScope.synthesize */ |
| @synthesize tree; |
| >> |
| |
| /** the implementation of returnScope methods */ |
| @returnScopeImplementation.methods() ::= << |
| /* AST returnScope.methods */ |
| - (<ASTLabelType> *)getTree |
| { |
| return tree; |
| } |
| |
| - (void) setTree:(<ASTLabelType> *)aTree |
| { |
| if (tree != aTree) { |
| if ( tree ) [tree release]; |
| if ( aTree ) [aTree retain]; |
| tree = aTree; |
| } |
| } |
| |
| - (void) dealloc |
| { |
| self.tree = nil; |
| [super dealloc]; |
| } |
| |
| >> |
| |
| /** Add a variable to track rule's return AST */ |
| ruleDeclarations() ::= << |
| /* AST ruleDeclarations */ |
| <super.ruleDeclarations()> |
| <ASTLabelType> *root_0 = nil;<\n> |
| >> |
| |
| ruleLabelDefs() ::= << |
| /* AST ruleLabelDefs */ |
| <super.ruleLabelDefs()> |
| <[ruleDescriptor.tokenLabels,ruleDescriptor.wildcardTreeLabels, |
| ruleDescriptor.wildcardTreeListLabels]:{it | <ASTLabelType> *<it.label.text>_tree=nil;}; separator="\n"> |
| <ruleDescriptor.tokenListLabels:{it | <ASTLabelType> *<it.label.text>_tree = nil;}; separator="\n"> |
| <ruleDescriptor.allTokenRefsInAltsWithRewrites:{it | ANTLRRewriteRuleTokenStream *stream_<it> = |
| [[ANTLRRewriteRule<rewriteElementType>Stream newANTLRRewriteRule<rewriteElementType>Stream:treeAdaptor |
| description:@"token <it>"] retain];}; separator="\n"> |
| <ruleDescriptor.allRuleRefsInAltsWithRewrites:{it | ANTLRRewriteRuleSubtreeStream *stream_<it> = |
| [[ANTLRRewriteRuleSubtreeStream newANTLRRewriteRuleSubtreeStream:treeAdaptor |
| description:@"rule <it>"] retain];}; separator="\n"> |
| >> |
| |
| ruleCleanUp() ::= << |
| /* AST ruleCleanUp */ |
| <super.ruleCleanUp()> |
| <[ruleDescriptor.allTokenRefsInAltsWithRewrites,ruleDescriptor.allRuleRefsInAltsWithRewrites]:{it | [stream_<it> release];}; separator="\n"> |
| <! |
| <if(ruleDescriptor.hasMultipleReturnValues)> |
| <if(backtracking)>if ( state.backtracking == 0 ) {<\n> |
| <endif> |
| [<prevRuleRootRef()> setTree:(<ASTLabelType> *)[treeAdaptor rulePostProcessing:root_0]];<\n> |
| [treeAdaptor setTokenBoundaries:[<prevRuleRootRef()> getTree] |
| From:[<prevRuleRootRef()> getStart] |
| To:[<prevRuleRootRef()> getStop]];<\n> |
| <if(backtracking)>}<\n> |
| <endif> |
| <endif> |
| [root_0 release]; |
| !> |
| >> |
| |
| rewriteCodeLabelsCleanUp() ::= << |
| /* AST rewriteCodeLabelsCleanUp */ |
| <referencedTokenLabels:{it | [stream_<it> release];}; separator="\n"> |
| <referencedTokenListLabels:{it | [stream_<it> release];}; separator="\n"> |
| <referencedRuleLabels:{it | [stream_<it> release];}; separator="\n"> |
| <referencedRuleListLabels:{it | [stream_<it> release];}; separator="\n"> |
| >> |
| |
| /** 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)> |
| <if(!rewriteMode)> |
| root_0 = (<ASTLabelType> *)[[[treeAdaptor class] newEmptyTree] retain];<\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 and track it for use in a rewrite rule */ |
| tokenRefTrack(token,label,elementIndex) ::= << |
| <! <super.tokenRef(...)> !> |
| <tokenRefBang(...)> <! Track implies no auto AST construction!> |
| <if(backtracking)> |
| if ( <actions.(actionScope).synpredgate> ) <endif> |
| [stream_<token> addElement:<label>];<\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) ::= << |
| <tokenRefTrack(...)> |
| <listLabel(elem=label,...)> |
| >> |
| |
| /** ^(ID ...) track for rewrite */ |
| tokenRefRuleRootTrack(token,label,elementIndex) ::= << |
| <! <super.tokenRef(...)> !> |
| <tokenRefBang(...)> |
| <if(backtracking)> |
| if ( !<actions.(actionScope).synpredgate> ) <endif> |
| [stream_<token> addElement:<label>];<\n> |
| >> |
| |
| /** Match ^(label+=TOKEN ...) track for rewrite */ |
| tokenRefRuleRootTrackAndListLabel(token,label,elementIndex) ::= << |
| <tokenRefRuleRootTrack(...)> |
| <listLabel(elem=label,...)> |
| >> |
| |
| /** rule when output=AST and tracking for rewrite */ |
| ruleRefTrack(rule,label,elementIndex,args,scope) ::= << |
| <super.ruleRef(...)> |
| <if(backtracking)>if ( <actions.(actionScope).synpredgate> ) <endif> |
| [stream_<rule.name> addElement:[<label> getTree]]; |
| >> |
| |
| /** x+=rule when output=AST and tracking for rewrite */ |
| ruleRefTrackAndListLabel(rule,label,elementIndex,args,scope) ::= << |
| <ruleRefTrack(...)> |
| <listLabel(elem={[<label> getTree]},...)> |
| >> |
| |
| /** ^(rule ...) rewrite */ |
| ruleRefRuleRootTrack(rule,label,elementIndex,args,scope) ::= << |
| <! <super.ruleRefRuleRoot(...)> !> |
| <ruleRefRuleRoot(...)> |
| <if(backtracking)>if ( <actions.(actionScope).synpredgate> ) <endif> |
| [stream_<rule.name> addElement:[<label> getTree]];<\n> |
| >> |
| |
| /** ^(x+=rule ...) rewrite */ |
| ruleRefRuleRootTrackAndListLabel(rule,label,elementIndex,args,scope) ::= << |
| <ruleRefRuleRootTrack(...)> |
| <listLabel(elem={[<label> getTree]},...)> |
| >> |
| |
| // 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=", "> |
| // wildcard labels: <[referencedWildcardLabels,referencedWildcardListLabels]; separator=", "> |
| <if(backtracking)> |
| if ( <actions.(actionScope).synpredgate> ) {<\n> |
| <endif> |
| <prevRuleRootRef()>.tree = root_0;<\n> |
| <rewriteCodeLabels()> |
| root_0 = (<ASTLabelType> *)[[[treeAdaptor class] newEmptyTree] retain];<\n> |
| <alts:rewriteAlt(); separator="else "> |
| <! if tree parser and rewrite=true !> |
| <if(TREE_PARSER)> |
| <if(rewriteMode)> |
| <prevRuleRootRef()>.tree = (<ASTLabelType>)[treeAdaptor rulePostProcessing:root_0]; |
| [input replaceChildren:[treeAdaptor getParent:retval.start] |
| From:[treeAdaptor getChildIndex:retval.start] |
| To:[treeAdaptor getChildIndex:_last] |
| With:retval.tree]; |
| <endif> |
| <endif> |
| <! if parser or tree-parser && rewrite!=true, we need to set result !> |
| <if(!TREE_PARSER)> |
| <prevRuleRootRef()>.tree = root_0;<\n> |
| <else> |
| <if(!rewriteMode)> |
| <prevRuleRootRef()>.tree = root_0;<\n> |
| <endif> |
| <endif> |
| <if(backtracking)> |
| } |
| <endif> |
| >> |
| |
| rewriteCodeLabels() ::= << |
| <referencedTokenLabels |
| :{it | ANTLRRewriteRule<rewriteElementType>Stream *stream_<it> = |
| [[ANTLRRewriteRule<rewriteElementType>Stream newANTLRRewriteRule<rewriteElementType>Stream:treeAdaptor description:@"token <it>" element:<it>] retain];}; |
| separator="\n" |
| > |
| <referencedTokenListLabels:{it | ANTLRRewriteRule<rewriteElementType>Stream *stream_<it> = |
| [[ANTLRRewriteRule<rewriteElementType>Stream newANTLRRewriteRule<rewriteElementType>Stream:treeAdaptor |
| description:@"token <it>" elements:list_<it>] retain];}; |
| separator="\n" |
| > |
| <referencedWildcardLabels:{it | RewriteRuleSubtreeStream stream_<it> = |
| [[ANTLRRewriteRuleSubtreeStream newANTLRRewriteRuleSubtreeStream:treeAdaptor |
| description:"wildcard <it>" element:<it>] retain];}; |
| separator="\n" |
| > |
| <referencedWildcardListLabels:{it | RewriteRuleSubtreeStream stream_<it> = |
| [[ANTLRRewriteRuleSubtreeStream newANTLRRewriteRuleSubtreeStream:treeAdaptor |
| descriptor:"wildcard <it>" elements:list_<it>] retain];}; |
| separator="\n" |
| > |
| <referencedRuleLabels:{it | ANTLRRewriteRuleSubtreeStream *stream_<it> = |
| [[ANTLRRewriteRuleSubtreeStream newANTLRRewriteRuleSubtreeStream:treeAdaptor |
| description:@"token <it>" element:<it>!=nil?[<it> getTree]:nil] retain];}; |
| separator="\n" |
| > |
| <referencedRuleListLabels:{it | ANTLRRewriteRuleSubtreeStream *stream_<it> = |
| [[ANTLRRewriteRuleSubtreeStream newANTLRRewriteRuleSubtreeStream:treeAdaptor |
| description:@"token <it>" elements:list_<it>] retain];}; |
| 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> hasNext]}; separator="||"> ) { |
| <alt> |
| } |
| <referencedElementsDeep:{el | [stream_<el> reset];<\n>}> |
| >> |
| |
| rewriteClosureBlock( |
| alt,rewriteBlockLevel, |
| referencedElementsDeep, // all nested refs |
| referencedElements, // elements in immediately block; no nested blocks |
| description) ::= |
| << |
| // <fileName>:<description> |
| while ( <referencedElements:{el | [stream_<el> hasNext]}; separator="||"> ) { |
| <alt> |
| } |
| <referencedElements:{el | [stream_<el> reset];<\n>}> |
| >> |
| |
| rewritePositiveClosureBlock( |
| alt,rewriteBlockLevel, |
| referencedElementsDeep, // all nested refs |
| referencedElements, // elements in immediately block; no nested blocks |
| description) ::= |
| << |
| // <fileName>:<description> |
| { |
| if ( !(<referencedElements:{el | [stream_<el> hasNext]}; separator=" || ">) ) { |
| @throw [ANTLRRewriteEarlyExitException newException]; |
| } |
| while ( <referencedElements:{el | [stream_<el> hasNext]}; separator=" || "> ) { |
| <alt> |
| } |
| <referencedElements:{el | [stream_<el> reset];<\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 = nil;" |
| |
| rewriteTree(root,children,description,enclosingTreeLevel,treeLevel) ::= << |
| // <fileName>:<description> |
| { |
| <ASTLabelType> *root_<treeLevel> = (<ASTLabelType> *)[[[treeAdaptor class] newEmptyTree] retain]; |
| <root:rewriteElement()> |
| <children:rewriteElement()> |
| [treeAdaptor addChild:root_<treeLevel> toTree:root_<enclosingTreeLevel>]; |
| }<\n> |
| >> |
| |
| rewriteElementList(elements) ::= "<elements:rewriteElement()>" |
| |
| rewriteElement(e) ::= << |
| <@pregen()> |
| <e.el> |
| >> |
| |
| /** Gen ID or ID[args] */ |
| rewriteTokenRef(token,elementIndex,terminalOptions,args) ::= << |
| // TODO: args: <args; separator=", "> |
| [treeAdaptor addChild:<createRewriteNodeFromElement(...)> toTree:root_<treeLevel>];<\n> |
| >> |
| |
| /** Gen $label ... where defined via label=ID */ |
| rewriteTokenLabelRef(label,elementIndex) ::= << |
| [treeAdaptor addChild:[stream_<label> nextNode] toTree:root_<treeLevel>];<\n> |
| >> |
| |
| /** Gen $label ... where defined via label+=ID */ |
| rewriteTokenListLabelRef(label,elementIndex) ::= << |
| [treeAdaptor addChild:[stream_<label> nextNode] toTree:root_<treeLevel>];<\n> |
| >> |
| |
| /** Gen ^($label ...) */ |
| rewriteTokenLabelRefRoot(label,elementIndex) ::= << |
| root_<treeLevel> = (<ASTLabelType> *)[treeAdaptor becomeRoot:[stream_<label> nextNode] old:root_<treeLevel>];<\n> |
| >> |
| |
| /** Gen ^($label ...) where label+=... */ |
| rewriteTokenListLabelRefRoot ::= rewriteTokenLabelRefRoot |
| |
| /** Gen ^(ID ...) or ^(ID[args] ...) */ |
| rewriteTokenRefRoot(token,elementIndex,terminalOptions,args) ::= << |
| root_<treeLevel> = (<ASTLabelType> *)[treeAdaptor becomeRoot:<createRewriteNodeFromElement(...)> old:root_<treeLevel>];<\n> |
| >> |
| |
| rewriteImaginaryTokenRef(args,token,terminalOptions,elementIndex) ::= << |
| [treeAdaptor addChild:<createImaginaryNode(tokenType=token, ...)> toTree:root_<treeLevel>];<\n> |
| >> |
| |
| rewriteImaginaryTokenRefRoot(args,token,terminalOptions,elementIndex) ::= << |
| root_<treeLevel> = (<ASTLabelType> *)[treeAdaptor becomeRoot:<createImaginaryNode(tokenType=token, ...)> old: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) ::= << |
| [treeAdaptor addChild:[stream_<rule> nextTree] toTree:root_<treeLevel>];<\n> |
| >> |
| |
| rewriteRuleRefRoot(rule) ::= << |
| root_<treeLevel> = (<ASTLabelType> *)[treeAdaptor becomeRoot:(id\<ANTLRTree>)[stream_<rule> nextNode] old:root_<treeLevel>];<\n> |
| >> |
| |
| rewriteNodeAction(action) ::= << |
| [treeAdaptor addChild:<action> toTree:root_<treeLevel>];<\n> |
| >> |
| |
| rewriteNodeActionRoot(action) ::= << |
| root_<treeLevel> = (<ASTLabelType> *)[treeAdaptor becomeRoot:<action> old:root_<treeLevel>];<\n> |
| >> |
| |
| /** Gen $ruleLabel ... where defined via ruleLabel=rule */ |
| rewriteRuleLabelRef(label) ::= << |
| [treeAdaptor addChild:[stream_<label> nextTree] toTree:root_<treeLevel>];<\n> |
| >> |
| |
| /** Gen $ruleLabel ... where defined via ruleLabel+=rule */ |
| rewriteRuleListLabelRef(label) ::= << |
| [treeAdaptor addChild:[stream_<label> nextTree] toTree:root_<treeLevel>];<\n> |
| >> |
| |
| /** Gen ^($ruleLabel ...) where ruleLabel=rule */ |
| rewriteRuleLabelRefRoot(label) ::= << |
| root_<treeLevel> = (<ASTLabelType> *)[treeAdaptor becomeRoot:[stream_<label> nextNode] old:root_<treeLevel>];<\n> |
| >> |
| |
| /** Gen ^($ruleLabel ...) where ruleLabel+=rule */ |
| rewriteRuleListLabelRefRoot(label) ::= << |
| root_<treeLevel> = (<ASTLabelType> *)[treeAdaptor becomeRoot:[stream_<label> nextNode] old:root_<treeLevel>];<\n> |
| >> |
| |
| rewriteWildcardLabelRef(label) ::= << |
| [treeAdaptor addChild:[stream_<label> nextTree] toTree:root_<treeLevel>];<\n> |
| >> |
| |
| createImaginaryNode(tokenType,terminalOptions,args) ::= << |
| <if(terminalOptions.node)> |
| [<terminalOptions.node> new<terminalOptions.node>:<tokenType> <if(args)>, <args; separator=", "><endif>] |
| <else> |
| <if(args)> |
| [[treeAdaptor createTree:<tokenType> <if(first(args))>FromToken:<first(args)><endif> <if(first(rest(args)))>Text:<first(rest(args))><else>Text:@"<tokenType>"<endif>] retain] |
| <else> |
| [[treeAdaptor createTree:<tokenType> Text:@"<tokenType>"] retain] |
| <endif> |
| <endif> |
| >> |
| |
| createRewriteNodeFromElement(token,terminalOptions,args) ::= << |
| <if(terminalOptions.node)> |
| [<terminalOptions.node> new<terminalOptions.node>:[stream_<token> nextToken]<if(args)>, <args; separator=", "><endif>] |
| <else> |
| <if(args)> <! must create new node from old !> |
| [[treeAdaptor createTree:<token> Text:<first(rest(args))> <args; separator=", ">] retain] |
| <else> |
| [stream_<token> nextNode] |
| <endif> |
| <endif> |
| >> |