/*
 [The "BSD license"]
 Copyright (c) 2006 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.
*/
/** Template overrides to add debugging to normal Objective-C output;
 *  If ASTs are built, then you'll also get ASTDbg.stg loaded.
 */
@headerFile.imports() ::= <<
<@super.imports()>
#import \<ANTLR/ANTLRDebug.h>
>>

@parserHeaderFile.memVars() ::= <<
NSInteger ruleLevel;
NSArray *ruleNames;
>>

@parserHeaderFile.methodsDecl() ::= <<
-(BOOL) evalPredicate:(NSString *)predicate matched:(BOOL)result;<\n>
>>

@genericParser.methods() ::= <<
<if(grammar.grammarIsRoot)>
AMutableArray *ruleNames = [AMutableArray arrayWithArray:{
    @"invalidRule", <grammar.allImportedRules:{rST | @"<rST.name>"}; wrap=@"\n    ", separator=", ">
};<\n>
<endif>
<if(grammar.grammarIsRoot)> <! grammar imports other grammar(s) !>
    ruleLevel = 0;
- (NSInteger) getRuleLevel { return ruleLevel; }
- (void) incRuleLevel { ruleLevel++; }
- (void) decRuleLevel { ruleLevel--; }
<if(profile)>
    <ctorForProfilingRootGrammar()>
<else>
    <ctorForRootGrammar()>
<endif>
<ctorForPredefinedListener()>
<else> <! imported grammar !>
- (NSInteger) getRuleLevel
{
    return <grammar.delegators:{g| <g:delegateName()>}>.getRuleLevel();
}<\n>

- (void) incRuleLevel
{
    <grammar.delegators:{g| <g:delegateName()>}>.incRuleLevel();
}<\n>
- (void) decRuleLevel
{
    <grammar.delegators:{g| <g:delegateName()>}>.decRuleLevel();
}<\n>
    <ctorForDelegateGrammar()>
<endif>
<if(profile)>
- (BOOL) alreadyParsedRule:(id<IntStream>) input Index:(NSInteger) ruleIndex
{
    [(Profiler)dbg examineRuleMemoization:input, ruleIndex, <grammar.composite.rootGrammar.recognizerName>.ruleNames objectAtIndex:ruleIndex];
    return super.alreadyParsedRule(input, ruleIndex);
}<\n>
- (void) memoize:(id<ANTLRIntStream>)input RuleIndex:(NSInteger)ruleIndex StartIndex:(NSInteger)ruleStartIndex
{
    [((Profiler)dbg) memoize:input RuleIndex:ruleIndex StartIndex:ruleStartIndex [<grammar.composite.rootGrammar.recognizerName> ruleNames[ruleIndex]];
    [super memoize:input RuleIndex:ruleIndex StartIndex:ruleStartIndex];
}<\n>
<endif>
- (BOOL) evalPredicate:(BOOL)result Pred:(NSString *)predicate
{
    [dbg semanticPredicate:result Pred:predicate];
    return result;
}<\n>
>>

@genericParser.init() ::= <<
ruleNames = [NSArray arrayWithObjects:<rules:{rST | @"<rST.ruleName>"}; separator=", ", wrap="\n	">, nil];<\n>
>>

@genericParser.dealloc() ::= <<
[ruleNames release];<\n>
>>

@genericParser.methods() ::= <<
-(BOOL) evalPredicate:(NSString *)predicate matched:(BOOL)result
{
	[debugListener semanticPredicate:predicate matched:result];
	return result;
}<\n>
>>

/* bug: can't use @super.superClassName()> */
@parserHeaderFile.superClassName() ::= "ANTLRDebug<if(TREE_PARSER)>Tree<endif>Parser"

@rule.preamble() ::= <<
@try { [debugListener enterRule:@"<ruleName>"];
if ( ruleLevel==0 ) [debugListener commence];
ruleLevel++;
[debugListener locationLine:<ruleDescriptor.tree.line> column:<ruleDescriptor.tree.column>];<\n>
>>

@rule.postamble() ::= <<
[debugListener locationLine:<ruleDescriptor.EORNode.line> column:<ruleDescriptor.EORNode.column>];<\n>
}
@finally {
    [debugListener exitRule:@"<ruleName>"];
    ruleLevel--;
    if ( ruleLevel==0 ) [debugListener terminate];
}<\n>
>>

/* these are handled in the runtime for now.
 * stinks, but that's the easiest way to avoid having to generate two
 * methods for each synpred

@synpred.start() ::= "[debugListener beginBacktrack:state.backtracking];"

@synpred.stop() ::= "[debugListener endBacktrack:state.backtracking wasSuccessful:success];"

 */

// Common debug event triggers used by region overrides below

enterSubRule() ::=
    "@try { [debugListener enterSubRule:<decisionNumber>];<\n>"

exitSubRule() ::=
    "} @finally { [debugListener exitSubRule:<decisionNumber>]; }<\n>"

enterDecision() ::=
    "@try { [debugListener enterDecision:<decisionNumber>];<\n>"

exitDecision() ::=
    "} @finally { [debugListener exitDecision:<decisionNumber>]; }<\n>"

enterAlt(n) ::= "[debugListener enterAlt:<n>];<\n>"

// Region overrides that tell various constructs to add debugging triggers

@block.predecision() ::= "<enterSubRule()><enterDecision()>"

@block.postdecision() ::= "<exitDecision()>"

@block.postbranch() ::= "<exitSubRule()>"

@ruleBlock.predecision() ::= "<enterDecision()>"

@ruleBlock.postdecision() ::= "<exitDecision()>"

@ruleBlockSingleAlt.prealt() ::= "<enterAlt(n=\"1\")>"

@blockSingleAlt.prealt() ::= "<enterAlt(n=\"1\")>"

@positiveClosureBlock.preloop() ::= "<enterSubRule()>"

@positiveClosureBlock.postloop() ::= "<exitSubRule()>"

@positiveClosureBlock.predecision() ::= "<enterDecision()>"

@positiveClosureBlock.postdecision() ::= "<exitDecision()>"

@positiveClosureBlock.earlyExitException() ::=
    "[debugListener recognitionException:eee];<\n>"

@closureBlock.preloop() ::= "<enterSubRule()>"

@closureBlock.postloop() ::= "<exitSubRule()>"

@closureBlock.predecision() ::= "<enterDecision()>"

@closureBlock.postdecision() ::= "<exitDecision()>"

@altSwitchCase.prealt() ::= "<enterAlt(n=i)>"

@element.prematch() ::=
    "[debugListener locationLine:<it.line> column:<it.pos>];"

@matchSet.mismatchedSetException() ::=
    "[debugListener recognitionException:mse];"

@dfaState.noViableAltException() ::= "[debugListener recognitionException:nvae];"

@dfaStateSwitch.noViableAltException() ::= "[debugListener recognitionException:nvae];"

dfaDecision(decisionNumber,description) ::= <<
@try {
    // isCyclicDecision is only necessary for the Profiler. Which I didn't do, yet.
    // isCyclicDecision = YES;
    <super.dfaDecision(...)>
}
@catch (ANTLRNoViableAltException *nvae) {
    [debugListener recognitionException:nvae];
    @throw nvae;
}
>>

@cyclicDFA.errorMethod() ::= <<
-(void) error:(ANTLRNoViableAltException *)nvae
{
    [[recognizer debugListener] recognitionException:nvae];
}
>>

/** Force predicate validation to trigger an event */
evalPredicate(pred,description) ::= <<
[self evalPredicate:@"<description>" result:<pred>];
>>
