| /** Support functions for traversing cyclic DFA states as laid |
| * out in static initialized structures by the code generator. |
| * |
| * A DFA implemented as a set of transition tables. |
| * |
| * Any state that has a semantic predicate edge is special; those states |
| * are generated with if-then-else structures in a ->specialStateTransition() |
| * which is generated by cyclicDFA template. |
| * |
| * There are at most 32767 states (16-bit signed short). |
| * Could get away with byte sometimes but would have to generate different |
| * types and the simulation code too. For a point of reference, the Java |
| * lexer's Tokens rule DFA has 326 states roughly. |
| */ |
| |
| // [The "BSD licence"] |
| // 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. |
| |
| #include <antlr3defs.h> |
| #include <antlr3cyclicdfa.h> |
| |
| #ifdef ANTLR3_WINDOWS |
| #pragma warning( disable : 4100 ) |
| #endif |
| |
| static void |
| noViableAlt(pANTLR3_BASE_RECOGNIZER rec, pANTLR3_CYCLIC_DFA cdfa, ANTLR3_UINT32 s) |
| { |
| // In backtracking mode, we just set the failed flag so that the |
| // alt can just exit right now. If we are parsing though, then |
| // we want the exception to be raised. |
| // |
| if (rec->state->backtracking > 0) |
| { |
| rec->state->failed = ANTLR3_TRUE; |
| } |
| else |
| { |
| rec->exConstruct(rec); |
| rec->state->exception->type = ANTLR3_NO_VIABLE_ALT_EXCEPTION; |
| rec->state->exception->message = cdfa->description; |
| rec->state->exception->decisionNum = cdfa->decisionNumber; |
| rec->state->exception->state = s; |
| } |
| } |
| |
| /** From the input stream, predict what alternative will succeed |
| * using this DFA (representing the covering regular approximation |
| * to the underlying CFL). Return an alternative number 1..n. Throw |
| * an exception upon error. |
| */ |
| ANTLR3_API ANTLR3_INT32 |
| antlr3dfapredict (void * ctx, pANTLR3_BASE_RECOGNIZER rec, pANTLR3_INT_STREAM is, pANTLR3_CYCLIC_DFA cdfa) |
| { |
| ANTLR3_MARKER mark; |
| ANTLR3_INT32 s; |
| ANTLR3_INT32 specialState; |
| ANTLR3_INT32 c; |
| |
| mark = is->mark(is); /* Store where we are right now */ |
| s = 0; /* Always start with state 0 */ |
| |
| for (;;) |
| { |
| /* Pick out any special state entry for this state |
| */ |
| specialState = cdfa->special[s]; |
| |
| /* Transition the special state and consume an input token |
| */ |
| if (specialState >= 0) |
| { |
| s = cdfa->specialStateTransition(ctx, rec, is, cdfa, specialState); |
| |
| // Error? |
| // |
| if (s<0) |
| { |
| // If the predicate/rule raised an exception then we leave it |
| // in tact, else we have an NVA. |
| // |
| if (rec->state->error != ANTLR3_TRUE) |
| { |
| noViableAlt(rec,cdfa, s); |
| } |
| is->rewind(is, mark); |
| return 0; |
| } |
| is->consume(is); |
| continue; |
| } |
| |
| /* Accept state? |
| */ |
| if (cdfa->accept[s] >= 1) |
| { |
| is->rewind(is, mark); |
| return cdfa->accept[s]; |
| } |
| |
| /* Look for a normal transition state based upon the input token element |
| */ |
| c = is->_LA(is, 1); |
| |
| /* Check against min and max for this state |
| */ |
| if (c>= cdfa->min[s] && c <= cdfa->max[s]) |
| { |
| ANTLR3_INT32 snext; |
| |
| /* What is the next state? |
| */ |
| snext = cdfa->transition[s][c - cdfa->min[s]]; |
| |
| if (snext < 0) |
| { |
| /* Was in range but not a normal transition |
| * must check EOT, which is like the else clause. |
| * eot[s]>=0 indicates that an EOT edge goes to another |
| * state. |
| */ |
| if (cdfa->eot[s] >= 0) |
| { |
| s = cdfa->eot[s]; |
| is->consume(is); |
| continue; |
| } |
| noViableAlt(rec,cdfa, s); |
| is->rewind(is, mark); |
| return 0; |
| } |
| |
| /* New current state - move to it |
| */ |
| s = snext; |
| is->consume(is); |
| continue; |
| } |
| /* EOT Transition? |
| */ |
| if (cdfa->eot[s] >= 0) |
| { |
| s = cdfa->eot[s]; |
| is->consume(is); |
| continue; |
| } |
| /* EOF transition to accept state? |
| */ |
| if ( c == ANTLR3_TOKEN_EOF && cdfa->eof[s] >= 0) |
| { |
| is->rewind(is, mark); |
| return cdfa->accept[cdfa->eof[s]]; |
| } |
| |
| /* No alt, so bomb |
| */ |
| noViableAlt(rec, cdfa, s); |
| is->rewind(is, mark); |
| return 0; |
| } |
| |
| } |
| |
| /** Default special state implementation |
| */ |
| ANTLR3_API ANTLR3_INT32 |
| antlr3dfaspecialStateTransition (void * ctx, pANTLR3_BASE_RECOGNIZER recognizer, pANTLR3_INT_STREAM is, pANTLR3_CYCLIC_DFA dfa, ANTLR3_INT32 s) |
| { |
| return -1; |
| } |
| |
| /* Default special transition implementation |
| */ |
| ANTLR3_API ANTLR3_INT32 |
| antlr3dfaspecialTransition (void * ctx, pANTLR3_BASE_RECOGNIZER recognizer, pANTLR3_INT_STREAM is, pANTLR3_CYCLIC_DFA dfa, ANTLR3_INT32 s) |
| { |
| return 0; |
| } |