| /* |
| [The "BSD license"] |
| Copyright (c) 2005-2009 Jim Idle, Temporal Wave LLC |
| http://www.temporal-wave.com |
| http://www.linkedin.com/in/jimidle |
| |
| 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 C output; |
| * If ASTs are built, then you'll also get ASTDbg.stg loaded. |
| */ |
| @genericParser.members() ::= << |
| <if(grammar.grammarIsRoot)> |
| const char * |
| ruleNames[] = |
| { |
| "invalidRule", <grammar.allImportedRules:{rST | "<rST.name>"}; wrap="\n ", separator=", "> |
| };<\n> |
| <endif> |
| <if(grammar.grammarIsRoot)> <! grammar imports other grammar(s) !> |
| static ANTLR3_UINT32 ruleLevel = 0; |
| static ANTLR3_UINT32 getRuleLevel() |
| { |
| return ruleLevel; |
| } |
| static void incRuleLevel() |
| { |
| ruleLevel++; |
| } |
| static void decRuleLevel() |
| { |
| ruleLevel--; |
| } |
| <else> <! imported grammar !> |
| static ANTLR3_UINT32 |
| getRuleLevel() |
| { |
| return <grammar.delegators:{g| <g:delegateName()>}>->getRuleLevel(); |
| } |
| static void incRuleLevel() |
| { |
| <grammar.delegators:{g| <g:delegateName()>}>->incRuleLevel(); |
| } |
| static void |
| decRuleLevel() |
| { |
| <grammar.delegators:{g| <g:delegateName()>}>.decRuleLevel(); |
| } |
| <endif> |
| <if(profile)> |
| // Profiling not yet implemented for C target |
| // |
| <endif> |
| <if(grammar.grammarIsRoot)> |
| <ctorForPredefinedListener()> |
| <else> |
| <ctorForDelegateGrammar()> |
| <endif> |
| |
| static ANTLR3_BOOLEAN |
| evalPredicate(p<name> ctx, ANTLR3_BOOLEAN result, const char * predicate) |
| { |
| DBG->semanticPredicate(DBG, result, predicate); |
| return result; |
| }<\n> |
| >> |
| |
| @genericParser.debugStuff() ::= << |
| <if(grammar.grammarIsRoot)> |
| <createListenerAndHandshake()> |
| <endif> |
| >> |
| |
| ctorForProfilingRootGrammar() ::= << |
| >> |
| |
| /** Basically we don't want to set any dbg listeners as root will have it. */ |
| ctorForDelegateGrammar() ::= << |
| |
| >> |
| |
| ctorForPredefinedListener() ::= << |
| |
| >> |
| |
| createListenerAndHandshake() ::= << |
| { |
| // DEBUG MODE code |
| // |
| pANTLR3_DEBUG_EVENT_LISTENER proxy; |
| proxy = antlr3DebugListenerNew(); |
| proxy->grammarFileName = INPUT->tokenSource->strFactory->newStr8(INPUT->tokenSource->strFactory, (pANTLR3_UINT8)ctx->getGrammarFileName()); |
| |
| <if(TREE_PARSER)> |
| proxy->adaptor = ADAPTOR; |
| <endif> |
| PARSER->setDebugListener(PARSER, proxy); |
| |
| // Try to connect to the debugger (waits forever for a connection) |
| // |
| proxy->handshake(proxy); |
| |
| // End DEBUG MODE code |
| // |
| } |
| >> |
| |
| |
| @rule.preamble() ::= << |
| if ( getRuleLevel()==0 ) |
| { |
| DBG->commence(DBG); |
| } |
| DBG->enterRule(DBG, getGrammarFileName(), (const char *)"<ruleName>"); |
| incRuleLevel(); |
| DBG->location(DBG, <ruleDescriptor.tree.line>, <ruleDescriptor.tree.column>);<\n> |
| >> |
| |
| @rule.postamble() ::= << |
| DBG->location(DBG, <ruleDescriptor.EORNode.line>, <ruleDescriptor.EORNode.column>);<\n> |
| DBG->exitRule(DBG, getGrammarFileName(), (const char *)"<ruleName>"); |
| decRuleLevel(); |
| if ( getRuleLevel()==0 ) |
| { |
| DBG->terminate(DBG); |
| } |
| <\n> |
| >> |
| |
| @checkRuleBacktrackFailure.debugClean() ::= << |
| DBG->exitRule(DBG, getGrammarFileName(), (const char *)"<ruleName>"); |
| decRuleLevel(); |
| >> |
| |
| @synpred.start() ::= "DBG->beginBacktrack(DBG, BACKTRACKING);" |
| |
| @synpred.stop() ::= "DBG->endBacktrack(DBG, BACKTRACKING, success);" |
| |
| // Common debug event triggers used by region overrides below |
| |
| enterSubRule() ::= |
| "DBG->enterSubRule(DBG, <decisionNumber>);<\n>" |
| |
| exitSubRule() ::= |
| "DBG->exitSubRule(DBG, <decisionNumber>);<\n>" |
| |
| enterDecision() ::= |
| "DBG->enterDecision(DBG, <decisionNumber>);<\n>" |
| |
| exitDecision() ::= |
| "DBG->exitDecision(DBG, <decisionNumber>);<\n>" |
| |
| enterAlt(n) ::= "DBG->enterAlt(DBG, <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() ::= |
| "DBG->recognitionException(DBG, EXCEPTION);<\n>" |
| |
| @closureBlock.preloop() ::= "<enterSubRule()>" |
| |
| @closureBlock.postloop() ::= "<exitSubRule()>" |
| |
| @closureBlock.predecision() ::= "<enterDecision()>" |
| |
| @closureBlock.postdecision() ::= "<exitDecision()>" |
| |
| @altSwitchCase.prealt() ::= "<enterAlt(altNum)>" |
| |
| @element.prematch() ::= |
| "DBG->location(DBG, <e.line>, <e.pos>);" // e is arg of element |
| |
| @matchSet.mismatchedSetException() ::= |
| "DBG->recognitionException(DBG, EXCEPTION);" |
| |
| @newNVException.noViableAltException() ::= "DBG->recognitionException(DBG, EXCEPTION);" |
| |
| dfaDecision(decisionNumber,description) ::= << |
| alt<decisionNumber> = cdfa<decisionNumber>.predict(ctx, RECOGNIZER, ISTREAM, &cdfa<decisionNumber>); |
| if (HASEXCEPTION()) |
| { |
| DBG->recognitionException(DBG, EXCEPTION); |
| goto rule<ruleDescriptor.name>Ex; |
| } |
| <checkRuleBacktrackFailure()> |
| >> |
| |
| @cyclicDFA.errorMethod() ::= << |
| //static void |
| //dfaError(p<name> ctx) |
| //{ |
| // DBG->recognitionException(DBG, EXCEPTION); |
| //} |
| >> |
| |
| /** Force predicate validation to trigger an event */ |
| evalPredicate(pred,description) ::= << |
| evalPredicate(ctx, <pred>, (const char *)"<description>") |
| >> |