예제 #1
0
        /** Fill a list of all NFA states visited during the parse */
        protected virtual void ParseEngine(string startRule,
                                           NFAState start,
                                           NFAState stop,
                                           IIntStream input,
                                           Stack <object> ruleInvocationStack,
                                           IDebugEventListener actions,
                                           IList <NFAState> visitedStates)
        {
            NFAState s = start;

            if (actions != null)
            {
                actions.EnterRule(s.nfa.Grammar.FileName, start.enclosingRule.Name);
            }
            int t = input.LA(1);

            while (s != stop)
            {
                if (visitedStates != null)
                {
                    visitedStates.Add(s);
                }
                //Console.Out.WriteLine( "parse state " + s.stateNumber + " input=" + s.nfa.Grammar.getTokenDisplayName( t ) );
                // CASE 1: decision state
                if (s.DecisionNumber > 0 && s.nfa.Grammar.GetNumberOfAltsForDecisionNFA(s) > 1)
                {
                    // decision point, must predict and jump to alt
                    DFA dfa = s.nfa.Grammar.GetLookaheadDFA(s.DecisionNumber);
                    //if ( s.nfa.Grammar.type != GrammarType.Lexer )
                    //{
                    //    Console.Out.WriteLine( "decision: " +
                    //                   dfa.getNFADecisionStartState().Description +
                    //                   " input=" + s.nfa.Grammar.getTokenDisplayName( t ) );
                    //}
                    int m            = input.Mark();
                    int predictedAlt = Predict(dfa);
                    if (predictedAlt == NFA.INVALID_ALT_NUMBER)
                    {
                        string description        = dfa.NFADecisionStartState.Description;
                        NoViableAltException nvae =
                            new NoViableAltException(description,
                                                     dfa.NfaStartStateDecisionNumber,
                                                     s.StateNumber,
                                                     input);
                        if (actions != null)
                        {
                            actions.RecognitionException(nvae);
                        }
                        input.Consume(); // recover
                        throw nvae;
                    }
                    input.Rewind(m);
                    int parseAlt =
                        s.TranslateDisplayAltToWalkAlt(predictedAlt);
                    //if ( s.nfa.Grammar.type != GrammarType.Lexer )
                    //{
                    //    Console.Out.WriteLine( "predicted alt " + predictedAlt + ", parseAlt " + parseAlt );
                    //}
                    NFAState alt;
                    if (parseAlt > s.nfa.Grammar.GetNumberOfAltsForDecisionNFA(s))
                    {
                        // implied branch of loop etc...
                        alt = s.nfa.Grammar.nfa.GetState(s.endOfBlockStateNumber);
                    }
                    else
                    {
                        alt = s.nfa.Grammar.GetNFAStateForAltOfDecision(s, parseAlt);
                    }
                    s = (NFAState)alt.transition[0].Target;
                    continue;
                }

                // CASE 2: finished matching a rule
                if (s.IsAcceptState)
                { // end of rule node
                    if (actions != null)
                    {
                        actions.ExitRule(s.nfa.Grammar.FileName, s.enclosingRule.Name);
                    }
                    if (ruleInvocationStack.Count == 0)
                    {
                        // done parsing.  Hit the start state.
                        //Console.Out.WriteLine( "stack empty in stop state for " + s.enclosingRule );
                        break;
                    }
                    // pop invoking state off the stack to know where to return to
                    NFAState invokingState = (NFAState)ruleInvocationStack.Pop();
                    RuleClosureTransition invokingTransition =
                        (RuleClosureTransition)invokingState.transition[0];
                    // move to node after state that invoked this rule
                    s = invokingTransition.FollowState;
                    continue;
                }

                Transition trans = s.transition[0];
                Label      label = trans.Label;
                if (label.IsSemanticPredicate)
                {
                    FailedPredicateException fpe =
                        new FailedPredicateException(input,
                                                     s.enclosingRule.Name,
                                                     "can't deal with predicates yet");
                    if (actions != null)
                    {
                        actions.RecognitionException(fpe);
                    }
                }

                // CASE 3: epsilon transition
                if (label.IsEpsilon)
                {
                    // CASE 3a: rule invocation state
                    if (trans is RuleClosureTransition)
                    {
                        ruleInvocationStack.Push(s);
                        s = (NFAState)trans.Target;
                        //Console.Out.WriteLine( "call " + s.enclosingRule.name + " from " + s.nfa.Grammar.getFileName() );
                        if (actions != null)
                        {
                            actions.EnterRule(s.nfa.Grammar.FileName, s.enclosingRule.Name);
                        }
                        // could be jumping to new grammar, make sure DFA created
                        if (!s.nfa.Grammar.AllDecisionDFAHaveBeenCreated)
                        {
                            s.nfa.Grammar.CreateLookaheadDFAs();
                        }
                    }
                    // CASE 3b: plain old epsilon transition, just move
                    else
                    {
                        s = (NFAState)trans.Target;
                    }
                }

                // CASE 4: match label on transition
                else if (label.Matches(t))
                {
                    if (actions != null)
                    {
                        if (s.nfa.Grammar.type == GrammarType.Parser ||
                            s.nfa.Grammar.type == GrammarType.Combined)
                        {
                            actions.ConsumeToken(((ITokenStream)input).LT(1));
                        }
                    }
                    s = (NFAState)s.transition[0].Target;
                    input.Consume();
                    t = input.LA(1);
                }

                // CASE 5: error condition; label is inconsistent with input
                else
                {
                    if (label.IsAtom)
                    {
                        MismatchedTokenException mte =
                            new MismatchedTokenException(label.Atom, input);
                        if (actions != null)
                        {
                            actions.RecognitionException(mte);
                        }
                        input.Consume(); // recover
                        throw mte;
                    }
                    else if (label.IsSet)
                    {
                        MismatchedSetException mse =
                            new MismatchedSetException(((IntervalSet)label.Set).ToRuntimeBitSet(),
                                                       input);
                        if (actions != null)
                        {
                            actions.RecognitionException(mse);
                        }
                        input.Consume(); // recover
                        throw mse;
                    }
                    else if (label.IsSemanticPredicate)
                    {
                        FailedPredicateException fpe =
                            new FailedPredicateException(input,
                                                         s.enclosingRule.Name,
                                                         label.SemanticContext.ToString());
                        if (actions != null)
                        {
                            actions.RecognitionException(fpe);
                        }
                        input.Consume(); // recover
                        throw fpe;
                    }
                    else
                    {
                        throw new RecognitionException(input);   // unknown error
                    }
                }
            }
            //Console.Out.WriteLine( "hit stop state for " + stop.enclosingRule );
            if (actions != null)
            {
                actions.ExitRule(s.nfa.Grammar.FileName, stop.enclosingRule.Name);
            }
        }
예제 #2
0
        /** Fill a list of all NFA states visited during the parse */
        protected virtual void ParseEngine( String startRule,
                                   NFAState start,
                                   NFAState stop,
                                   IIntStream input,
                                   Stack<object> ruleInvocationStack,
                                   IDebugEventListener actions,
                                   IList visitedStates )
        {
            NFAState s = start;
            if ( actions != null )
            {
                actions.EnterRule( s.nfa.grammar.FileName, start.enclosingRule.Name );
            }
            int t = input.LA( 1 );
            while ( s != stop )
            {
                if ( visitedStates != null )
                {
                    visitedStates.Add( s );
                }
                //Console.Out.WriteLine( "parse state " + s.stateNumber + " input=" + s.nfa.grammar.getTokenDisplayName( t ) );
                // CASE 1: decision state
                if ( s.DecisionNumber > 0 && s.nfa.grammar.GetNumberOfAltsForDecisionNFA( s ) > 1 )
                {
                    // decision point, must predict and jump to alt
                    DFA dfa = s.nfa.grammar.GetLookaheadDFA( s.DecisionNumber );
                    //if ( s.nfa.grammar.type != GrammarType.Lexer )
                    //{
                    //    Console.Out.WriteLine( "decision: " +
                    //                   dfa.getNFADecisionStartState().Description +
                    //                   " input=" + s.nfa.grammar.getTokenDisplayName( t ) );
                    //}
                    int m = input.Mark();
                    int predictedAlt = Predict( dfa );
                    if ( predictedAlt == NFA.INVALID_ALT_NUMBER )
                    {
                        String description = dfa.NFADecisionStartState.Description;
                        NoViableAltException nvae =
                            new NoViableAltException( description,
                                                          dfa.DecisionNumber,
                                                          s.stateNumber,
                                                          input );
                        if ( actions != null )
                        {
                            actions.RecognitionException( nvae );
                        }
                        input.Consume(); // recover
                        throw nvae;
                    }
                    input.Rewind( m );
                    int parseAlt =
                        s.TranslateDisplayAltToWalkAlt( predictedAlt );
                    //if ( s.nfa.grammar.type != GrammarType.Lexer )
                    //{
                    //    Console.Out.WriteLine( "predicted alt " + predictedAlt + ", parseAlt " + parseAlt );
                    //}
                    NFAState alt;
                    if ( parseAlt > s.nfa.grammar.GetNumberOfAltsForDecisionNFA( s ) )
                    {
                        // implied branch of loop etc...
                        alt = s.nfa.grammar.nfa.GetState( s.endOfBlockStateNumber );
                    }
                    else
                    {
                        alt = s.nfa.grammar.GetNFAStateForAltOfDecision( s, parseAlt );
                    }
                    s = (NFAState)alt.transition[0].target;
                    continue;
                }

                // CASE 2: finished matching a rule
                if ( s.IsAcceptState )
                { // end of rule node
                    if ( actions != null )
                    {
                        actions.ExitRule( s.nfa.grammar.FileName, s.enclosingRule.Name );
                    }
                    if ( ruleInvocationStack.Count == 0 )
                    {
                        // done parsing.  Hit the start state.
                        //Console.Out.WriteLine( "stack empty in stop state for " + s.enclosingRule );
                        break;
                    }
                    // pop invoking state off the stack to know where to return to
                    NFAState invokingState = (NFAState)ruleInvocationStack.Pop();
                    RuleClosureTransition invokingTransition =
                            (RuleClosureTransition)invokingState.transition[0];
                    // move to node after state that invoked this rule
                    s = invokingTransition.followState;
                    continue;
                }

                Transition trans = s.transition[0];
                Label label = trans.label;
                if ( label.IsSemanticPredicate )
                {
                    FailedPredicateException fpe =
                        new FailedPredicateException( input,
                                                     s.enclosingRule.Name,
                                                     "can't deal with predicates yet" );
                    if ( actions != null )
                    {
                        actions.RecognitionException( fpe );
                    }
                }

                // CASE 3: epsilon transition
                if ( label.IsEpsilon )
                {
                    // CASE 3a: rule invocation state
                    if ( trans is RuleClosureTransition )
                    {
                        ruleInvocationStack.Push( s );
                        s = (NFAState)trans.target;
                        //Console.Out.WriteLine( "call " + s.enclosingRule.name + " from " + s.nfa.grammar.getFileName() );
                        if ( actions != null )
                        {
                            actions.EnterRule( s.nfa.grammar.FileName, s.enclosingRule.Name );
                        }
                        // could be jumping to new grammar, make sure DFA created
                        if ( !s.nfa.grammar.AllDecisionDFAHaveBeenCreated )
                        {
                            s.nfa.grammar.CreateLookaheadDFAs();
                        }
                    }
                    // CASE 3b: plain old epsilon transition, just move
                    else
                    {
                        s = (NFAState)trans.target;
                    }
                }

                // CASE 4: match label on transition
                else if ( label.Matches( t ) )
                {
                    if ( actions != null )
                    {
                        if ( s.nfa.grammar.type == GrammarType.Parser ||
                             s.nfa.grammar.type == GrammarType.Combined )
                        {
                            actions.ConsumeToken( ( (ITokenStream)input ).LT( 1 ) );
                        }
                    }
                    s = (NFAState)s.transition[0].target;
                    input.Consume();
                    t = input.LA( 1 );
                }

                // CASE 5: error condition; label is inconsistent with input
                else
                {
                    if ( label.IsAtom )
                    {
                        MismatchedTokenException mte =
                            new MismatchedTokenException( label.Atom, input );
                        if ( actions != null )
                        {
                            actions.RecognitionException( mte );
                        }
                        input.Consume(); // recover
                        throw mte;
                    }
                    else if ( label.IsSet )
                    {
                        MismatchedSetException mse =
                            new MismatchedSetException( ( (IntervalSet)label.Set ).ToRuntimeBitSet(),
                                                       input );
                        if ( actions != null )
                        {
                            actions.RecognitionException( mse );
                        }
                        input.Consume(); // recover
                        throw mse;
                    }
                    else if ( label.IsSemanticPredicate )
                    {
                        FailedPredicateException fpe =
                            new FailedPredicateException( input,
                                                         s.enclosingRule.Name,
                                                         label.SemanticContext.ToString() );
                        if ( actions != null )
                        {
                            actions.RecognitionException( fpe );
                        }
                        input.Consume(); // recover
                        throw fpe;
                    }
                    else
                    {
                        throw new RecognitionException( input ); // unknown error
                    }
                }
            }
            //Console.Out.WriteLine( "hit stop state for " + stop.enclosingRule );
            if ( actions != null )
            {
                actions.ExitRule( s.nfa.grammar.FileName, stop.enclosingRule.Name );
            }
        }