Home | History | Annotate | Download | only in C
      1 /*
      2  [The "BSD license"]
      3  Copyright (c) 2005-2009 Jim Idle, Temporal Wave LLC
      4  http://www.temporal-wave.com
      5  http://www.linkedin.com/in/jimidle
      6 
      7  All rights reserved.
      8 
      9  Redistribution and use in source and binary forms, with or without
     10  modification, are permitted provided that the following conditions
     11  are met:
     12  1. Redistributions of source code must retain the above copyright
     13     notice, this list of conditions and the following disclaimer.
     14  2. Redistributions in binary form must reproduce the above copyright
     15     notice, this list of conditions and the following disclaimer in the
     16     documentation and/or other materials provided with the distribution.
     17  3. The name of the author may not be used to endorse or promote products
     18     derived from this software without specific prior written permission.
     19 
     20  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     21  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     22  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     23  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     24  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     25  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     26  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     27  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     28  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     29  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     30 */
     31 /** Template overrides to add debugging to normal C output;
     32  *  If ASTs are built, then you'll also get ASTDbg.stg loaded.
     33  */
     34 @genericParser.members() ::= <<
     35 <if(grammar.grammarIsRoot)>
     36 const char *
     37 ruleNames[] =
     38 	{
     39 		"invalidRule", <grammar.allImportedRules:{rST | "<rST.name>"}; wrap="\n		", separator=", ">
     40 	};<\n>
     41 <endif>
     42 <if(grammar.grammarIsRoot)> <! grammar imports other grammar(s) !>
     43 static ANTLR3_UINT32 ruleLevel = 0;
     44 static ANTLR3_UINT32 getRuleLevel()
     45 {
     46 	return ruleLevel;
     47 }
     48 static void incRuleLevel()
     49 {
     50 	ruleLevel++;
     51 }
     52 static void decRuleLevel()
     53 {
     54 	ruleLevel--;
     55 }
     56 <else> <! imported grammar !>
     57 static ANTLR3_UINT32
     58 getRuleLevel()
     59 {
     60 	return <grammar.delegators:{g| <g:delegateName()>}>->getRuleLevel();
     61 }
     62 static void incRuleLevel()
     63 {
     64 	<grammar.delegators:{g| <g:delegateName()>}>->incRuleLevel();
     65 }
     66 static void
     67 decRuleLevel()
     68 {
     69 	<grammar.delegators:{g| <g:delegateName()>}>.decRuleLevel();
     70 }
     71 <endif>
     72 <if(profile)>
     73 // Profiling not yet implemented for C target
     74 //
     75 <endif>
     76 <if(grammar.grammarIsRoot)>
     77 <ctorForPredefinedListener()>
     78 <else>
     79 <ctorForDelegateGrammar()>
     80 <endif>
     81 
     82 static ANTLR3_BOOLEAN
     83 evalPredicate(p<name> ctx, ANTLR3_BOOLEAN result, const char * predicate)
     84 {
     85     DBG->semanticPredicate(DBG, result, predicate);
     86     return result;
     87 }<\n>
     88 >>
     89 
     90 @genericParser.debugStuff() ::= <<
     91 <if(grammar.grammarIsRoot)>
     92 <createListenerAndHandshake()>
     93 <endif>
     94 >>
     95 
     96 ctorForProfilingRootGrammar() ::= <<
     97 >>
     98 
     99 /** Basically we don't want to set any dbg listeners as root will have it. */
    100 ctorForDelegateGrammar() ::= <<
    101 
    102 >>
    103 
    104 ctorForPredefinedListener() ::= <<
    105 
    106 >>
    107 
    108 createListenerAndHandshake() ::= <<
    109 {
    110 	// DEBUG MODE code
    111 	//
    112 	pANTLR3_DEBUG_EVENT_LISTENER	 proxy;
    113 	proxy = antlr3DebugListenerNew();
    114 	proxy->grammarFileName = INPUT->tokenSource->strFactory->newStr8(INPUT->tokenSource->strFactory, (pANTLR3_UINT8)ctx->getGrammarFileName());
    115 
    116 <if(TREE_PARSER)>
    117 	proxy->adaptor = ADAPTOR;
    118 <endif>
    119 	PARSER->setDebugListener(PARSER, proxy);
    120 
    121 	// Try to connect to the debugger (waits forever for a connection)
    122 	//
    123 	proxy->handshake(proxy);
    124 
    125 	// End DEBUG MODE code
    126 	//
    127 }
    128 >>
    129 
    130 
    131 @rule.preamble() ::= <<
    132 if ( getRuleLevel()==0 )
    133 {
    134 	DBG->commence(DBG);
    135 }
    136 DBG->enterRule(DBG, getGrammarFileName(), (const char *)"<ruleName>");
    137 incRuleLevel();
    138 DBG->location(DBG, <ruleDescriptor.tree.line>, <ruleDescriptor.tree.column>);<\n>
    139 >>
    140 
    141 @rule.postamble() ::= <<
    142 DBG->location(DBG, <ruleDescriptor.EORNode.line>, <ruleDescriptor.EORNode.column>);<\n>
    143 DBG->exitRule(DBG, getGrammarFileName(), (const char *)"<ruleName>");
    144 decRuleLevel();
    145 if ( getRuleLevel()==0 )
    146 {
    147 	DBG->terminate(DBG);
    148 }
    149 <\n>
    150 >>
    151 
    152 @checkRuleBacktrackFailure.debugClean() ::= <<
    153 DBG->exitRule(DBG, getGrammarFileName(), (const char *)"<ruleName>");
    154 decRuleLevel();
    155 >>
    156 
    157 @synpred.start() ::= "DBG->beginBacktrack(DBG, BACKTRACKING);"
    158 
    159 @synpred.stop() ::= "DBG->endBacktrack(DBG, BACKTRACKING, success);"
    160 
    161 // Common debug event triggers used by region overrides below
    162 
    163 enterSubRule() ::=
    164     "DBG->enterSubRule(DBG, <decisionNumber>);<\n>"
    165 
    166 exitSubRule() ::=
    167     "DBG->exitSubRule(DBG, <decisionNumber>);<\n>"
    168 
    169 enterDecision() ::=
    170     "DBG->enterDecision(DBG, <decisionNumber>);<\n>"
    171 
    172 exitDecision() ::=
    173     "DBG->exitDecision(DBG, <decisionNumber>);<\n>"
    174 
    175 enterAlt(n) ::= "DBG->enterAlt(DBG, <n>);<\n>"
    176 
    177 // Region overrides that tell various constructs to add debugging triggers
    178 
    179 @block.predecision() ::= "<enterSubRule()><enterDecision()>"
    180 
    181 @block.postdecision() ::= "<exitDecision()>"
    182 
    183 @block.postbranch() ::= "<exitSubRule()>"
    184 
    185 @ruleBlock.predecision() ::= "<enterDecision()>"
    186 
    187 @ruleBlock.postdecision() ::= "<exitDecision()>"
    188 
    189 @ruleBlockSingleAlt.prealt() ::= "<enterAlt(n=\"1\")>"
    190 
    191 @blockSingleAlt.prealt() ::= "<enterAlt(n=\"1\")>"
    192 
    193 @positiveClosureBlock.preloop() ::= "<enterSubRule()>"
    194 
    195 @positiveClosureBlock.postloop() ::= "<exitSubRule()>"
    196 
    197 @positiveClosureBlock.predecision() ::= "<enterDecision()>"
    198 
    199 @positiveClosureBlock.postdecision() ::= "<exitDecision()>"
    200 
    201 @positiveClosureBlock.earlyExitException() ::=
    202     "DBG->recognitionException(DBG, EXCEPTION);<\n>"
    203 
    204 @closureBlock.preloop() ::= "<enterSubRule()>"
    205 
    206 @closureBlock.postloop() ::= "<exitSubRule()>"
    207 
    208 @closureBlock.predecision() ::= "<enterDecision()>"
    209 
    210 @closureBlock.postdecision() ::= "<exitDecision()>"
    211 
    212 @altSwitchCase.prealt() ::= "<enterAlt(altNum)>"
    213 
    214 @element.prematch() ::=
    215     "DBG->location(DBG, <e.line>, <e.pos>);" // e is arg of element
    216 
    217 @matchSet.mismatchedSetException() ::=
    218     "DBG->recognitionException(DBG, EXCEPTION);"
    219 
    220 @newNVException.noViableAltException() ::= "DBG->recognitionException(DBG, EXCEPTION);"
    221 
    222 dfaDecision(decisionNumber,description) ::= <<
    223 alt<decisionNumber> = cdfa<decisionNumber>.predict(ctx, RECOGNIZER, ISTREAM, &cdfa<decisionNumber>);
    224 if  (HASEXCEPTION())
    225 {
    226 	DBG->recognitionException(DBG, EXCEPTION);
    227     goto rule<ruleDescriptor.name>Ex;
    228 }
    229 <checkRuleBacktrackFailure()>
    230 >>
    231 
    232 @cyclicDFA.errorMethod() ::= <<
    233 //static void
    234 //dfaError(p<name> ctx)
    235 //{
    236 //    DBG->recognitionException(DBG, EXCEPTION);
    237 //}
    238 >>
    239 
    240 /** Force predicate validation to trigger an event */
    241 evalPredicate(pred,description) ::= <<
    242 evalPredicate(ctx, <pred>, (const char *)"<description>")
    243 >>
    244