/*
 [The "BSD license"]
 Copyright (c) 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.
*/

/** Templates for building ASTs during tree parsing.
 *
 *  Deal with many combinations.  Dimensions are:
 *  Auto build or rewrite
 *    no label, label, list label  (label/no-label handled together)
 *    child, root
 *    token, set, rule, wildcard
 *
 *  Each combination has its own template except that label/no label
 *  is combined into tokenRef, ruleRef, ...
 */

/* addition memVars for returnscopes */
@returnScopeInterface.memVars() ::= <<
/* ASTTreeParser returnScopeInterface.memVars */
<recognizer.ASTLabelType; null="CommonTree"> *tree;
>>

/** the interface of returnScope methodsDecl */
@returnScopeInterface.methodsDecl() ::= <<
/* ASTTreeParser returnScopeInterface.methodsDecl */
- (<recognizer.ASTLabelType; null="CommonTree"> *)getTree;
- (void) setTree:(<recognizer.ASTLabelType; null="CommonTree"> *)aTree;<\n>
>>

/** the implementation of returnScope methods */
@returnScope.methods() ::= <<
/* ASTTreeParser returnScope.methods */
- (<ASTLabelType> *)getTree
{
    return tree;
}

- (void) setTree:(<ASTLabelType> *)aTree
{
    if (tree != aTree) {
        if (tree != nil) [tree release];
        if (aTree != nil) [aTree retain];
        tree = aTree;
    }
}

- (void) dealloc
{
    [self setTree:nil];
    [super dealloc];
}

@synthesize tree;
>>

@returnScopeProperties() ::= <<
@property (retain) <recognizer.ASTLabelType; null="CommonTree"> *tree;
>>

/** Add a variable to track last element matched */
ruleDeclarations() ::= <<
/* ASTTreeParser ruleDeclarations */
<super.ruleDeclarations()>
<ASTLabelType> *_first_0 = nil;
<ASTLabelType> *_last = nil;<\n>
>>

/** What to emit when there is no rewrite rule.  For auto build
 *  mode, does nothing.
 */
noRewrite(rewriteBlockLevel, treeLevel) ::= <<
/* ASTTreeParser noRewrite */
<if(backtracking)>if ( <actions.(actionScope).synpredgate> ) {<endif>
<if(rewriteMode)>
retval.tree = (<ASTLabelType> *)_first_0;
if ( [treeAdaptor getParent:retval.tree] != nil && [treeAdaptor isNil:[treeAdaptor getParent:retval.tree]] ) )
    retval.tree = (<ASTLabelType> *)[treeAdaptor getParent:retval.tree];
<endif>
<if(backtracking)>}<endif>
>>

/** match ^(root children) in tree parser; override here to
 *  add tree construction actions.
 */
tree(root, actionsAfterRoot, children, nullableChildList,
     enclosingTreeLevel, treeLevel) ::= <<
/* ASTTreeParser tree */
_last = (<ASTLabelType> *)[input LT:1];
{
<ASTLabelType> *_save_last_<treeLevel> = _last;
<ASTLabelType> *_first_<treeLevel> = nil;
<if(!rewriteMode)>
<ASTLabelType> *root_<treeLevel> = [[[treeAdaptor class] newEmptyTree] retain];
<endif>
<root:element()>
<if(rewriteMode)>
<if(backtracking)>if ( <actions.(actionScope).synpredgate> )<endif>
<if(root.el.rule)>
if ( _first_<enclosingTreeLevel>==nil ) _first_<enclosingTreeLevel> = <root.el.label>.tree;
<else>
if ( _first_<enclosingTreeLevel>==nil ) _first_<enclosingTreeLevel> = <root.el.label>;
<endif>
<endif>
<actionsAfterRoot:element()>
<if(nullableChildList)>
if ( [input LA:1] == TokenTypeDOWN ) {
    [self match:input TokenType:TokenTypeDOWN Follow:nil]; <checkRuleBacktrackFailure()>
    <children:element()>
    [self match:input TokenType:TokenTypeUP Follow:nil]; <checkRuleBacktrackFailure()>
}
<else>
[self match:input TokenType:TokenTypeDOWN Follow:nil]; <checkRuleBacktrackFailure()>
<children:element()>
[self match:input TokenType:TokenTypeUP Follow:nil]; <checkRuleBacktrackFailure()>
<endif>
<if(!rewriteMode)>
[treeAdaptor addChild:root_<treeLevel> toTree:root_<enclosingTreeLevel>];
<endif>
_last = _save_last_<treeLevel>;
}<\n>
>>

// TOKEN AST STUFF

/** ID! and output=AST (same as plain tokenRef) 'cept add
 *  setting of _last
 */
tokenRefBang(token,label,elementIndex,terminalOptions) ::= <<
/* ASTTreeParser tokenRefBang */
_last = (<ASTLabelType> *)[input LT:1];
<super.tokenRef(...)>
>>

/** ID auto construct */
tokenRef(token,label,elementIndex,terminalOptions) ::= <<
/* ASTTreeParser tokenRef */
_last = (<ASTLabelType> *)[input LT:1];
<super.tokenRef(...)>
<if(!rewriteMode)>
<if(backtracking)>if ( <actions.(actionScope).synpredgate> ) {<endif>
<if(terminalOptions.node)>
    <label>_tree = [<terminalOptions.node> new<terminalOptions.node>:<label>];
<else>
    <label>_tree = (<ASTLabelType> *)[treeAdaptor dupNode:<label>];
<endif><\n>
    [treeAdaptor addChild:<label>_tree toTree:root_<treeLevel>];
<if(backtracking)>}<endif>
<else> <! rewrite mode !>
<if(backtracking)>if ( <actions.(actionScope).synpredgate> )<endif>
if ( _first_<treeLevel>==nil ) _first_<treeLevel> = <label>;
<endif>
>>

/** label+=TOKEN auto construct */
tokenRefAndListLabel(token,label,elementIndex,terminalOptions) ::= <<
/* ASTTreeParser tokenRefAndListLabel */
<tokenRef(...)>
<listLabel(elem=label,...)>
>>

/** ^(ID ...) auto construct */
tokenRefRuleRoot(token,label,elementIndex) ::= <<
/* ASTTreeParser tokenRefRuleRoot */
_last = (<ASTLabelType> *)[input LT:1];
<super.tokenRef(...)>
<if(!rewriteMode)>
<if(backtracking)>if ( <actions.(actionScope).synpredgate> ) {<endif>
<if(terminalOptions.node)>
<label>_tree = [<terminalOptions.node> new<terminalOptions.node>:<label>];
<else>
<label>_tree = (<ASTLabelType> *)[treeAdaptor dupNode:<label>];
<endif><\n>
root_<treeLevel> = (<ASTLabelType> *)[treeAdaptor becomeRoot:<label>_tree old:root_<treeLevel>];
<if(backtracking)>}<endif>
<endif>
>>

/** Match ^(label+=TOKEN ...) auto construct */
tokenRefRuleRootAndListLabel(token,label,elementIndex,terminalOptions) ::= <<
/* ASTTreeParser tokenRefRuleRootAndListLabel */
<tokenRefRuleRoot(...)>
<listLabel(elem=label,...)>
>>

/** Match . wildcard and auto dup the node/subtree */
wildcard(token,label,elementIndex,terminalOptions) ::= <<
/* ASTTreeParser wildcard */
_last = (<ASTLabelType> *)[input LT:1];
<super.wildcard(...)>
<if(!rewriteMode)>
<if(backtracking)>if ( <actions.(actionScope).synpredgate> ) {<endif>
<label>_tree = (<ASTLabelType> *)[adaptor dupTree:<label>];
[adaptor addChild:<label>_tree toTree:root_<treeLevel>];
<if(backtracking)>}<endif>
<else> <! rewrite mode !>
<if(backtracking)>if ( <actions.(actionScope).synpredgate> )<endif>
if ( _first_<treeLevel> == nil ) _first_<treeLevel> = <label>;
<endif>
>>

// SET AST

matchSet(s,label,terminalOptions,elementIndex,postmatchCode) ::= <<
/* ASTTreeParser matchSet */
_last = (<ASTLabelType> *)[input LT:1];
<super.matchSet(postmatchCode={
<if(!rewriteMode)>
<if(backtracking)>if ( <actions.(actionScope).synpredgate> ) {<endif>
<if(terminalOptions.node)>
<label>_tree = [<terminalOptions.node> new<terminalOptions.node>:<label>];
<else>
<label>_tree = (<ASTLabelType> *)[adaptor dupNode:<label>];
<endif><\n>
[adaptor addChild:<label>_tree toTree:root_<treeLevel>];
<if(backtracking)>\}<endif>
<endif>
}, ...
)>
>>

matchRuleBlockSet(s,label,terminalOptions,elementIndex,postmatchCode,treeLevel="0") ::= <<
/* ASTTreeParser matchRuleBlockSet */
<matchSet(...)>
<noRewrite(...)> <! set return tree !>
>>

matchSetBang(s,label,terminalOptions,elementIndex,postmatchCode) ::= <<
/* ASTTreeParser matchSetBang */
_last = (<ASTLabelType> *)[input LT:1];
<super.matchSet(...)>
>>

matchSetRuleRoot(s,label,terminalOptions,elementIndex,debug) ::= <<
/* ASTTreeParser matchSetRuleRoot */
<super.matchSet(postmatchCode={
<if(!rewriteMode)>
<if(backtracking)>if ( <actions.(actionScope).synpredgate> ) {<endif>
<if(terminalOptions.node)>
<label>_tree = [<terminalOptions.node> new<terminalOptions.node>:<label>];
<else>
<label>_tree = (<ASTLabelType> *)[adaptor dupNode:<label>];
<endif><\n>
root_<treeLevel> = (<ASTLabelType> *)[adaptor becomeRoot:<label>_tree old:root_<treeLevel>];
<if(backtracking)>\}<endif>
<endif>
}, ...
)>
>>

// RULE REF AST

/** rule auto construct */
ruleRef(rule,label,elementIndex,args,scope) ::= <<
/* ASTTreeParser ruleRef */
_last = (<ASTLabelType> *)[input LT:1];
<super.ruleRef(...)>
<if(backtracking)>if ( <actions.(actionScope).synpredgate> ) <endif>
<if(!rewriteMode)>
    [treeAdaptor addChild:<label>.tree toTree:root_<treeLevel>];
<else> <! rewrite mode !>
if ( _first_<treeLevel> == nil ) _first_<treeLevel> = <label>.tree;
<endif>
>>

/** x+=rule auto construct */
ruleRefAndListLabel(rule,label,elementIndex,args,scope) ::= <<
/* ASTTreeParser ruleRefAndListLabel */
<ruleRef(...)>
<! <listLabel(elem = "["+label+" getTree]",...)> !>
<listLabel(elem = {[<label> getTree]},...)>
>>

/** ^(rule ...) auto construct */
ruleRefRuleRoot(rule,label,elementIndex,args,scope) ::= <<
/* ASTTreeParser ruleRefRuleRoot */
_last = (<ASTLabelType> *)[input LT:1];
<super.ruleRef(...)>
<if(!rewriteMode)>
<if(backtracking)>if ( state.backtracking == 0 ) <endif>
root_<treeLevel> = (<ASTLabelType> *)[treeAdaptor becomeRoot:<label>.tree old:root_<treeLevel>];
<endif>
>>

/** ^(x+=rule ...) auto construct */
ruleRefRuleRootAndListLabel(rule,label,elementIndex,args,scope) ::= <<
/* ASTTreeParser ruleRefRuleRootAndListLabel */
<ruleRefRuleRoot(...)>
<listLabel(elem = {[<label> getTree]},...)>
>>

/** rule when output=AST and tracking for rewrite */
ruleRefTrack(rule,label,elementIndex,args,scope) ::= <<
/* ASTTreeParser ruleRefTrack */
_last = (<ASTLabelType> *)[input LT:1];
<super.ruleRefTrack(...)>
>>

/** x+=rule when output=AST and tracking for rewrite */
ruleRefTrackAndListLabel(rule,label,elementIndex,args,scope) ::= <<
/* ASTTreeParser ruleRefTrackAndListLabel */
_last = (<ASTLabelType> *)[input LT:1];
<super.ruleRefTrackAndListLabel(...)>
>>

/** ^(rule ...) rewrite */
ruleRefRuleRootTrack(rule,label,elementIndex,args,scope) ::= <<
/* ASTTreeParser ruleRefRuleRootTrack */
_last = (<ASTLabelType> *)[input LT:1];
<super.ruleRefRootTrack(...)>
>>

/** ^(x+=rule ...) rewrite */
ruleRefRuleRootTrackAndListLabel(rule,label,elementIndex,args,scope) ::= <<
/* ASTTreeParser ruleRefRuleRootTrackAndListLabel */
_last = (<ASTLabelType> *)[input LT:1];
<super.ruleRefRuleRootTrackAndListLabel(...)>
>>

/** Streams for token refs are tree nodes now; override to
 *  change nextToken to nextNode.
 */
createRewriteNodeFromElement(token,terminalOptions,scope) ::= <<
/* ASTTreeParser createRewriteNodeFromElement */
<if(terminalOptions.node)>
<! new <terminalOptions.node>(stream_<token>.nextNode()) !>
[[[<terminalOptions.node>(stream_<token> alloc] init] nextNode];
<else>
<! stream_<token>.nextNode() !>
[stream_<token> nextNode]
<endif>
>>

ruleCleanUp() ::= <<
/* ASTTreeParser ruleCleanUp */
<super.ruleCleanUp()>
<if(!rewriteMode)>
<if(backtracking)>if ( <actions.(actionScope).synpredgate> ) {<\n><endif>
retval.tree = (<ASTLabelType> *)[treeAdaptor rulePostProcessing:root_0];
<if(backtracking)>}<endif>
<endif>
>>
