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

/** Add a variable to track last element matched */
ruleDeclarations() ::= <<
<super.ruleDeclarations()>
<if(!ruleDescriptor.isSynPred)>
<ASTLabelType> _first_0 = null;
<ASTLabelType> _last = null;<\n>
<endif>
>>

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

/** match ^(root children) in tree parser; override here to
 *  add tree construction actions.
 */
tree(root, actionsAfterRoot, children, nullableChildList,
	 enclosingTreeLevel, treeLevel) ::= <<
<if(!ruleDescriptor.isSynPred)>
_last = (<ASTLabelType>)input.LT(1);
{
<ASTLabelType> _save_last_<treeLevel> = _last;
<ASTLabelType> _first_<treeLevel> = null;
<if(!rewriteMode)>
<ASTLabelType> root_<treeLevel> = (<ASTLabelType>)adaptor.nil();
<endif>
<root:element()>
<if(rewriteMode)>
<if(backtracking)>if ( <actions.(actionScope).synpredgate> )<endif>
<if(root.el.rule)>
if ( _first_<enclosingTreeLevel>==null ) _first_<enclosingTreeLevel> = (<ASTLabelType>)<root.el.label>.getTree();
<elseif(root.el.label)>
if ( _first_<enclosingTreeLevel>==null ) _first_<enclosingTreeLevel> = <root.el.label>;
<endif>
<endif>
<actionsAfterRoot:element()>
<if(nullableChildList)>
if ( input.LA(1)==Token.DOWN ) {
	match(input, Token.DOWN, null); <checkRuleBacktrackFailure()>
	<children:element()>
	match(input, Token.UP, null); <checkRuleBacktrackFailure()>
}
<else>
match(input, Token.DOWN, null); <checkRuleBacktrackFailure()>
<children:element()>
match(input, Token.UP, null); <checkRuleBacktrackFailure()>
<endif>
<if(!rewriteMode)>
adaptor.addChild(root_<enclosingTreeLevel>, root_<treeLevel>);
<endif>
_last = _save_last_<treeLevel>;
}<\n>
<else>
<super.tree(...)>
<endif>
>>

// TOKEN AST STUFF

/** ID! and output=AST (same as plain tokenRef) 'cept add
 *  setting of _last
 */
tokenRefBang(token,label,elementIndex,terminalOptions={}) ::= <<
<if(!ruleDescriptor.isSynPred)>
_last = (<ASTLabelType>)input.LT(1);
<super.tokenRef(...)>
<else>
<super.tokenRefBang(...)>
<endif>
>>

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

/** label+=TOKEN auto construct */
tokenRefAndListLabel(token,label,elementIndex,terminalOptions={}) ::= <<
<if(!ruleDescriptor.isSynPred)>
<tokenRef(...)>
<listLabel(elem=label,...)>
<else>
<super.tokenRefAndListLabel(...)>
<endif>
>>

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

/** Match ^(label+=TOKEN ...) auto construct */
tokenRefRuleRootAndListLabel(token,label,elementIndex,terminalOptions={}) ::= <<
<if(!ruleDescriptor.isSynPred)>
<tokenRefRuleRoot(...)>
<listLabel(elem=label,...)>
<else>
<super.tokenRefRuleRootAndListLabel(...)>
<endif>
>>

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

// SET AST

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

matchRuleBlockSet(s,label,elementIndex,postmatchCode,treeLevel="0",terminalOptions={}) ::= <<
<if(!ruleDescriptor.isSynPred)>
<matchSet(...)>
<noRewrite(...)> <! set return tree !>
<else>
<super.matchRuleBlockSet(...)>
<endif>
>>

matchSetBang(s,label,elementIndex,postmatchCode,terminalOptions={}) ::= <<
<if(!ruleDescriptor.isSynPred)>
_last = (<ASTLabelType>)input.LT(1);
<super.matchSet(...)>
<else>
<super.matchSetBang(...)>
<endif>
>>

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

// RULE REF AST

/** rule auto construct */
ruleRef(rule,label,elementIndex,args,scope) ::= <<
<if(!ruleDescriptor.isSynPred)>
_last = (<ASTLabelType>)input.LT(1);
<super.ruleRef(...)>
<if(backtracking)>if ( <actions.(actionScope).synpredgate> ) <endif>
<if(!rewriteMode)>
adaptor.addChild(root_<treeLevel>, <label>.getTree());
<else> <! rewrite mode !>
if ( _first_<treeLevel>==null ) _first_<treeLevel> = (<ASTLabelType>)<label>.getTree();
<endif>
<else>
<super.ruleRef(...)>
<endif>
>>

/** x+=rule auto construct */
ruleRefAndListLabel(rule,label,elementIndex,args,scope) ::= <<
<if(!ruleDescriptor.isSynPred)>
<ruleRef(...)>
<listLabel(label, {<label>.getTree()})>
<else>
<super.ruleRefAndListLabel(...)>
<endif>
>>

/** ^(rule ...) auto construct */
ruleRefRuleRoot(rule,label,elementIndex,args,scope) ::= <<
<if(!ruleDescriptor.isSynPred)>
_last = (<ASTLabelType>)input.LT(1);
<super.ruleRef(...)>
<if(!rewriteMode)>
<if(backtracking)>if ( <actions.(actionScope).synpredgate> ) <endif>root_<treeLevel> = (<ASTLabelType>)adaptor.becomeRoot(<label>.getTree(), root_<treeLevel>);
<endif>
<else>
<super.ruleRefRuleRoot(...)>
<endif>
>>

/** ^(x+=rule ...) auto construct */
ruleRefRuleRootAndListLabel(rule,label,elementIndex,args,scope) ::= <<
<if(!ruleDescriptor.isSynPred)>
<ruleRefRuleRoot(...)>
<listLabel(label, {<label>.getTree()})>
<else>
<super.ruleRefRuleRootAndListLabel(...)>
<endif>
>>

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

/** x+=rule when output=AST and tracking for rewrite */
ruleRefTrackAndListLabel(rule,label,elementIndex,args,scope) ::= <<
<if(!ruleDescriptor.isSynPred)>
_last = (<ASTLabelType>)input.LT(1);
<super.ruleRefTrackAndListLabel(...)>
<else>
<super.ruleRefTrackAndListLabel(...)>
<endif>
>>

/** ^(rule ...) rewrite */
ruleRefRuleRootTrack(rule,label,elementIndex,args,scope) ::= <<
<if(!ruleDescriptor.isSynPred)>
_last = (<ASTLabelType>)input.LT(1);
<super.ruleRefRootTrack(...)>
<else>
<super.ruleRefRootTrack(...)>
<endif>
>>

/** ^(x+=rule ...) rewrite */
ruleRefRuleRootTrackAndListLabel(rule,label,elementIndex,args,scope) ::= <<
<if(!ruleDescriptor.isSynPred)>
_last = (<ASTLabelType>)input.LT(1);
<super.ruleRefRuleRootTrackAndListLabel(...)>
<else>
<super.ruleRefRuleRootTrackAndListLabel(...)>
<endif>
>>

/** Streams for token refs are tree nodes now; override to
 *  change nextToken to nextNode.
 */
createRewriteNodeFromElement(token,args,terminalOptions={}) ::= <<
<if(terminalOptions.node)>
new <terminalOptions.node>(stream_<token>.nextNode())
<else>
stream_<token>.nextNode()
<endif>
>>

ruleCleanUp() ::= <<
<super.ruleCleanUp()>
<if(!ruleDescriptor.isSynPred)>
<if(!rewriteMode)>
<if(backtracking)>if ( <actions.(actionScope).synpredgate> ) {<\n><endif>
retval.tree = (<ASTLabelType>)adaptor.rulePostProcessing(root_0);
<if(backtracking)>}<endif>
<endif>
<endif>
>>
