/*
 [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.
*/

finishedBacktracking(block) ::= <<
<if(backtracking)>
if <actions.(actionScope).synpredgate>:
    <block>
<else>
<block>
<endif>
>>

@outputFile.imports() ::= <<
<@super.imports()>
<if(!TREE_PARSER)><! tree parser would already have imported !>
from antlr3.tree import *<\n>
<endif>
>>

/** Add an adaptor property that knows how to build trees */
@genericParser.init() ::= <<
self._adaptor = None
self.adaptor = CommonTreeAdaptor()
<@super.init()>
>>

@genericParser.members() ::= <<
<@super.members()>
<astAccessor()>
>>

astAccessor() ::= <<
def getTreeAdaptor(self):
    return self._adaptor

def setTreeAdaptor(self, adaptor):
    self._adaptor = adaptor
    <grammar.directDelegates:{g|self.<g:delegateName()>.adaptor = adaptor}; separator="\n">

adaptor = property(getTreeAdaptor, setTreeAdaptor)
>>

@returnScope.ruleReturnInit() ::= <<
self.tree = None
>>


/** Add a variable to track rule's return AST */
ruleDeclarations() ::= <<
<super.ruleDeclarations()>
root_0 = None<\n>
>>

ruleLabelDefs() ::= <<
<super.ruleLabelDefs()>
<[ruleDescriptor.tokenLabels,ruleDescriptor.wildcardTreeLabels,
  ruleDescriptor.wildcardTreeListLabels]
    :{it | <it.label.text>_tree = None}; separator="\n">
<ruleDescriptor.tokenListLabels:{it | <it.label.text>_tree = None}; separator="\n">
<ruleDescriptor.allTokenRefsInAltsWithRewrites
    :{it | stream_<it> = RewriteRule<rewriteElementType>Stream(self._adaptor, "token <it>")}; separator="\n">
<ruleDescriptor.allRuleRefsInAltsWithRewrites
    :{it | stream_<it> = RewriteRuleSubtreeStream(self._adaptor, "rule <it>")}; 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 = self._adaptor.nil()<\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,terminalOptions={}) ::= <<
<tokenRefBang(...)> <! Track implies no auto AST construction!>
<finishedBacktracking({stream_<token>.add(<label>)})>
>>

/** 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(...)>
<finishedBacktracking({stream_<token>.add(<label>)})>
>>

/** Match ^(label+=TOKEN ...) track for rewrite */
tokenRefRuleRootTrackAndListLabel(token,label,elementIndex,terminalOptions={}) ::= <<
<tokenRefRuleRootTrack(...)>
<listLabel(elem=label,...)>
>>

/** rule when output=AST and tracking for rewrite */
ruleRefTrack(rule,label,elementIndex,args,scope) ::= <<
<super.ruleRef(...)>
<finishedBacktracking({stream_<rule.name>.add(<label>.tree)})>
>>

/** x+=rule when output=AST and tracking for rewrite */
ruleRefTrackAndListLabel(rule,label,elementIndex,args,scope) ::= <<
<ruleRefTrack(...)>
<listLabel(label, {<label>.tree})>
>>

/** ^(rule ...) rewrite */
ruleRefRuleRootTrack(rule,label,elementIndex,args,scope) ::= <<
<ruleRefRuleRoot(...)>
<finishedBacktracking({stream_<rule.name>.add(<label>.tree)})>
>>

/** ^(x+=rule ...) rewrite */
ruleRefRuleRootTrackAndListLabel(rule,label,elementIndex,args,scope) ::= <<
<ruleRefRuleRootTrack(...)>
<listLabel(label, {<label>.tree})>
>>

// 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=", ">
<finishedBacktracking({
<prevRuleRootRef()>.tree = root_0
<rewriteCodeLabels()>
root_0 = self._adaptor.nil()
<first(alts):rewriteAltFirst(); anchor>

<rest(alts):{a | el<rewriteAltRest(a)>}; anchor, separator="\n\n">

<! if tree parser and rewrite=true !>
<if(TREE_PARSER)>
<if(rewriteMode)>
<prevRuleRootRef()>.tree = self._adaptor.rulePostProcessing(root_0)
self.input.replaceChildren(
    self._adaptor.getParent(retval.start),
    self._adaptor.getChildIndex(retval.start),
    self._adaptor.getChildIndex(_last),
    retval.tree
    )<\n>
<endif>
<endif>

<! if parser or tree-parser and 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>
})>
>>

rewriteCodeLabels() ::= <<
<referencedTokenLabels
    :{it | stream_<it> = RewriteRule<rewriteElementType>Stream(self._adaptor, "token <it>", <it>)};
    separator="\n"
>
<referencedTokenListLabels
    :{it | stream_<it> = RewriteRule<rewriteElementType>Stream(self._adaptor, "token <it>", list_<it>)};
    separator="\n"
>
<referencedWildcardLabels
    :{it | stream_<it> = RewriteRuleSubtreeStream(self._adaptor, "wildcard <it>", <it>)};
    separator="\n"
>
<referencedWildcardListLabels
    :{it | stream_<it> = RewriteRuleSubtreeStream(self._adaptor, "wildcard <it>", list_<it>)};
    separator="\n"
>
<referencedRuleLabels
    :{it |
if <it> is not None:
    stream_<it> = RewriteRuleSubtreeStream(self._adaptor, "rule <it>", <it>.tree)
else:
    stream_<it> = RewriteRuleSubtreeStream(self._adaptor, "token <it>", None)
};
    separator="\n"
>
<referencedRuleListLabels
    :{it| stream_<it> = RewriteRuleSubtreeStream(self._adaptor, "token <it>", list_<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>.hasNext()}; separator=" or ">:
    <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=" or ">:
    <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 not (<referencedElements:{el | stream_<el>.hasNext()}; separator=" or ">):
    raise RewriteEarlyExitException()

while <referencedElements:{el | stream_<el>.hasNext()}; separator=" or ">:
    <alt>

<referencedElements:{el | stream_<el>.reset()<\n>}>
>>

rewriteAltRest(a) ::= <<
<if(a.pred)>if <a.pred>:
    # <a.description>
    <a.alt>
<else>se: <! little hack to get if .. elif .. else block right !>
    # <a.description>
    <a.alt>
<endif>
>>

rewriteAltFirst(a) ::= <<
<if(a.pred)>
if <a.pred>:
    # <a.description>
    <a.alt>
<else>
# <a.description>
<a.alt>
<endif>
>>

/** For empty rewrites: "r : ... -> ;" */
rewriteEmptyAlt() ::= "root_0 = None"

rewriteTree(root,children,description,enclosingTreeLevel,treeLevel) ::= <<
# <fileName>:<description>
root_<treeLevel> = self._adaptor.nil()
<root:rewriteElement()>
<children:rewriteElement()>
self._adaptor.addChild(root_<enclosingTreeLevel>, root_<treeLevel>)<\n>
>>

rewriteElementList(elements) ::= "<elements:rewriteElement()>"

rewriteElement(e) ::= <<
<@pregen><@end>
<e.el>
>>

/** Gen ID or ID[args] */
rewriteTokenRef(token,elementIndex,args,terminalOptions={}) ::= <<
self._adaptor.addChild(root_<treeLevel>, <createRewriteNodeFromElement(...)>)<\n>
>>

/** Gen $label ... where defined via label=ID */
rewriteTokenLabelRef(label,elementIndex) ::= <<
self._adaptor.addChild(root_<treeLevel>, stream_<label>.nextNode())<\n>
>>

/** Gen $label ... where defined via label+=ID */
rewriteTokenListLabelRef(label,elementIndex) ::= <<
self._adaptor.addChild(root_<treeLevel>, stream_<label>.nextNode())<\n>
>>

/** Gen ^($label ...) */
rewriteTokenLabelRefRoot(label,elementIndex) ::= <<
root_<treeLevel> = self._adaptor.becomeRoot(stream_<label>.nextNode(), root_<treeLevel>)<\n>
>>

/** Gen ^($label ...) where label+=... */
rewriteTokenListLabelRefRoot ::= rewriteTokenLabelRefRoot

/** Gen ^(ID ...) or ^(ID[args] ...) */
rewriteTokenRefRoot(token,elementIndex,args,terminalOptions={}) ::= <<
root_<treeLevel> = self._adaptor.becomeRoot(<createRewriteNodeFromElement(...)>, root_<treeLevel>)<\n>
>>

rewriteImaginaryTokenRef(args,token,elementIndex,terminalOptions={}) ::= <<
self._adaptor.addChild(root_<treeLevel>, <createImaginaryNode(token, args, terminalOptions)>)<\n>
>>

rewriteImaginaryTokenRefRoot(args,token,elementIndex,terminalOptions={}) ::= <<
root_<treeLevel> = self._adaptor.becomeRoot(<createImaginaryNode(token, args, terminalOptions)>, root_<treeLevel>)<\n>
>>

/** plain -> {foo} action */
rewriteAction(action) ::= <<
<!FIXME(96,untested)!>
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) ::= <<
self._adaptor.addChild(root_<treeLevel>, stream_<rule>.nextTree())<\n>
>>

rewriteRuleRefRoot(rule) ::= <<
root_<treeLevel> = self._adaptor.becomeRoot(stream_<rule>.nextNode(), root_<treeLevel>)<\n>
>>

rewriteNodeAction(action) ::= <<
self._adaptor.addChild(root_<treeLevel>, <action>)<\n>
>>

rewriteNodeActionRoot(action) ::= <<
root_<treeLevel> = self._adaptor.becomeRoot(<action>, root_<treeLevel>)<\n>
>>

/** Gen $ruleLabel ... where defined via ruleLabel=rule */
rewriteRuleLabelRef(label) ::= <<
self._adaptor.addChild(root_<treeLevel>, stream_<label>.nextTree())<\n>
>>

/** Gen $ruleLabel ... where defined via ruleLabel+=rule */
rewriteRuleListLabelRef(label) ::= <<
self._adaptor.addChild(root_<treeLevel>, stream_<label>.nextTree())<\n>
>>

/** Gen ^($ruleLabel ...) where ruleLabel=rule */
rewriteRuleLabelRefRoot(label) ::= <<
root_<treeLevel> = self._adaptor.becomeRoot(stream_<label>.nextNode(), root_<treeLevel>)<\n>
>>

/** Gen ^($ruleLabel ...) where ruleLabel+=rule */
rewriteRuleListLabelRefRoot(label) ::= <<
root_<treeLevel> = self._adaptor.becomeRoot(stream_<label>.nextNode(), root_<treeLevel>)<\n>
>>

rewriteWildcardLabelRef(label) ::= <<
self._adaptor.addChild(root_<treeLevel>, stream_<label>.nextTree())<\n>
>>

createImaginaryNode(tokenType,args,terminalOptions={}) ::= <<
<if(terminalOptions.node)>
<! new MethodNode(IDLabel, args) !>
<terminalOptions.node>(<tokenType><if(args)>, <args; separator=", "><endif>)
<else>
<if (!args)>self._adaptor.createFromType(<tokenType>, "<tokenType>")
<else>self._adaptor.create(<tokenType>, <args; separator=", ">)
<endif>
<endif>
>>

//<! need to call different adaptor.create*() methods depending of argument count !>
//<if (!args)>self._adaptor.createFromType(<tokenType>, "<tokenType>")
//<else><if (!rest(args))>self._adaptor.createFromType(<tokenType>, <first(args)>)
//<else><if (!rest(rest(args)))>self._adaptor.createFromToken(<tokenType>, <first(args)>, <first(rest(args))>)
//<endif>
//<endif>
//<endif>


createRewriteNodeFromElement(token,args,terminalOptions={}) ::= <<
<if(terminalOptions.node)>
<terminalOptions.node>(stream_<token>.nextToken()<if(args)>, <args; separator=", "><endif>)
<else>
<if(args)> <! must create new node from old !>
<! need to call different adaptor.create*() methods depending of argument count !>
<if (!args)>self._adaptor.createFromType(<token>, "<token>")
<else><if (!rest(args))>self._adaptor.createFromToken(<token>, <first(args)>)
<else><if (!rest(rest(args)))>self._adaptor.createFromToken(<token>, <first(args)>, <first(rest(args))>)
<endif>
<endif>
<endif>
<else>
stream_<token>.nextNode()
<endif>
<endif>
>>
