示例#1
0
 public RuleClosureTransition( Rule rule,
                              NFAState ruleStart,
                              NFAState followState )
     : base(Label.EPSILON, ruleStart)
 {
     this.rule = rule;
     this.followState = followState;
 }
示例#2
0
 /** From list of lookahead sets (one per alt in decision), create
  *  an LL(1) DFA.  One edge per set.
  *
  *  s0-{alt1}->:o=>1
  *  | \
  *  |  -{alt2}->:o=>2
  *  |
  *  ...
  */
 public LL1DFA( int decisionNumber, NFAState decisionStartState, LookaheadSet[] altLook )
     : base(decisionNumber, decisionStartState)
 {
     DFAState s0 = NewState();
     StartState = s0;
     UnreachableAlts.Clear();
     for ( int alt = 1; alt < altLook.Length; alt++ )
     {
         DFAState acceptAltState = NewState();
         acceptAltState.IsAcceptState = true;
         SetAcceptState( alt, acceptAltState );
         acceptAltState.LookaheadDepth = 1;
         acceptAltState.CachedUniquelyPredicatedAlt = alt;
         Label e = GetLabelForSet( altLook[alt].TokenTypeSet );
         s0.AddTransition( acceptAltState, e );
     }
 }
示例#3
0
文件: LL1DFA.cs 项目: bszafko/antlrcs
 /** From list of lookahead sets (one per alt in decision), create
  *  an LL(1) DFA.  One edge per set.
  *
  *  s0-{alt1}->:o=>1
  *  | \
  *  |  -{alt2}->:o=>2
  *  |
  *  ...
  */
 public LL1DFA( int decisionNumber, NFAState decisionStartState, LookaheadSet[] altLook )
 {
     DFAState s0 = NewState();
     startState = s0;
     nfa = decisionStartState.nfa;
     NumberOfAlts = nfa.grammar.GetNumberOfAltsForDecisionNFA( decisionStartState );
     this.decisionNumber = decisionNumber;
     this.NFADecisionStartState = decisionStartState;
     InitAltRelatedInfo();
     UnreachableAlts = null;
     for ( int alt = 1; alt < altLook.Length; alt++ )
     {
         DFAState acceptAltState = NewState();
         acceptAltState.acceptState = true;
         SetAcceptState( alt, acceptAltState );
         acceptAltState.LookaheadDepth = 1;
         acceptAltState.cachedUniquelyPredicatedAlt = alt;
         Label e = GetLabelForSet( altLook[alt].tokenTypeSet );
         s0.AddTransition( acceptAltState, e );
     }
 }
示例#4
0
 private void TransitionBetweenStates( NFAState a, NFAState b, int label )
 {
     Transition e = new Transition( label, b );
     a.AddTransition( e );
 }
示例#5
0
 public virtual NFAState NewState()
 {
     NFAState n = new NFAState( _nfa );
     int state = _nfa.GetNewNFAStateNumber();
     n.StateNumber = state;
     _nfa.AddState( n );
     n.enclosingRule = _currentRule;
     return n;
 }
示例#6
0
        public static DFA CreateFromNfa(int decisionNumber, NFAState decisionStartState)
        {
            DFA dfa = new DFA(decisionNumber, decisionStartState);

            //long start = JSystem.currentTimeMillis();
            NFAToDFAConverter nfaConverter = new NFAToDFAConverter( dfa );
            try
            {
                nfaConverter.Convert();

                // figure out if there are problems with decision
                dfa.Verify();

                if ( !dfa.Probe.IsDeterministic || dfa.Probe.AnalysisOverflowed )
                {
                    dfa.Probe.IssueWarnings();
                }

                // must be after verify as it computes cyclic, needed by this routine
                // should be after warnings because early termination or something
                // will not allow the reset to operate properly in some cases.
                dfa.ResetStateNumbersToBeContiguous();

                //long stop = JSystem.currentTimeMillis();
                //[email protected]("verify cost: "+(int)(stop-start)+" ms");
            }
            catch ( NonLLStarDecisionException /*nonLL*/ )
            {
                dfa.Probe.ReportNonLLStarDecision( dfa );
                // >1 alt recurses, k=* and no auto backtrack nor manual sem/syn
                if ( !dfa.OkToRetryWithK1 )
                {
                    dfa.Probe.IssueWarnings();
                }
            }

            return dfa;
        }
示例#7
0
 public virtual NFAConfiguration AddNFAConfiguration( NFAState state,
                                             int alt,
                                             NFAContext context,
                                             SemanticContext semanticContext )
 {
     NFAConfiguration c = new NFAConfiguration( state.stateNumber,
                                               alt,
                                               context,
                                               semanticContext );
     AddNFAConfiguration( state, c );
     return c;
 }
示例#8
0
 public virtual void SetDecisionNFA( int decision, NFAState state )
 {
     Decision d = CreateDecision( decision );
     d.startState = state;
 }
示例#9
0
 /** Decisions are linked together with transition(1).  Count how
  *  many there are.  This is here rather than in NFAState because
  *  a grammar decides how NFAs are put together to form a decision.
  */
 public virtual int GetNumberOfAltsForDecisionNFA( NFAState decisionState )
 {
     if ( decisionState == null )
     {
         return 0;
     }
     int n = 1;
     NFAState p = decisionState;
     while ( p.transition[1] != null )
     {
         n++;
         p = (NFAState)p.transition[1].Target;
     }
     return n;
 }
示例#10
0
 public virtual LookaheadSet First( NFAState s )
 {
     return ll1Analyzer.First( s );
 }
示例#11
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 );
            }
        }
示例#12
0
        protected virtual SemanticContext GetPredicatesCore( NFAState s, NFAState altStartState )
        {
            //[email protected]("_getPredicates("+s+")");
            if ( s.IsAcceptState )
            {
                return null;
            }

            // avoid infinite loops from (..)* etc...
            if ( _lookBusy.Contains( s ) )
            {
                return null;
            }
            _lookBusy.Add( s );

            Transition transition0 = s.transition[0];
            // no transitions
            if ( transition0 == null )
            {
                return null;
            }

            // not a predicate and not even an epsilon
            if ( !( transition0.label.IsSemanticPredicate ||
                   transition0.label.IsEpsilon ) )
            {
                return null;
            }

            SemanticContext p = null;
            SemanticContext p0 = null;
            SemanticContext p1 = null;
            if ( transition0.label.IsSemanticPredicate )
            {
                //[email protected]("pred "+transition0.label);
                p = transition0.label.SemanticContext;
                // ignore backtracking preds not on left edge for this decision
                if ( ( (SemanticContext.Predicate)p ).predicateAST.Type ==
                      ANTLRParser.BACKTRACK_SEMPRED &&
                     s == altStartState.transition[0].target )
                {
                    p = null; // don't count
                }
            }

            // get preds from beyond this state
            p0 = GetPredicatesCore( (NFAState)transition0.target, altStartState );

            // get preds from other transition
            Transition transition1 = s.transition[1];
            if ( transition1 != null )
            {
                p1 = GetPredicatesCore( (NFAState)transition1.target, altStartState );
            }

            // join this&following-right|following-down
            return SemanticContext.And( p, SemanticContext.Or( p0, p1 ) );
        }
示例#13
0
        protected virtual LookaheadSet FirstCore( NFAState s, bool chaseFollowTransitions )
        {
            /*
            [email protected]("_LOOK("+s+") in rule "+s.enclosingRule);
            if ( s.transition[0] instanceof RuleClosureTransition ) {
                [email protected]("go to rule "+((NFAState)s.transition[0].target).enclosingRule);
            }
            */
            if ( !chaseFollowTransitions && s.IsAcceptState )
            {
                if ( _grammar.type == GrammarType.Lexer )
                {
                    // FOLLOW makes no sense (at the moment!) for lexical rules.
                    // assume all char can follow
                    return new LookaheadSet( IntervalSet.COMPLETE_SET );
                }
                return new LookaheadSet( Label.EOR_TOKEN_TYPE );
            }

            if ( _lookBusy.Contains( s ) )
            {
                // return a copy of an empty set; we may modify set inline
                return new LookaheadSet();
            }
            _lookBusy.Add( s );

            Transition transition0 = s.transition[0];
            if ( transition0 == null )
            {
                return null;
            }

            if ( transition0.label.IsAtom )
            {
                int atom = transition0.label.Atom;
                return new LookaheadSet( atom );
            }
            if ( transition0.label.IsSet )
            {
                IIntSet sl = transition0.label.Set;
                return new LookaheadSet( sl );
            }

            // compute FIRST of transition 0
            LookaheadSet tset = null;
            // if transition 0 is a rule call and we don't want FOLLOW, check cache
            if ( !chaseFollowTransitions && transition0 is RuleClosureTransition )
            {
                LookaheadSet prev = _firstCache.get( (NFAState)transition0.target );
                if ( prev != null )
                {
                    tset = new LookaheadSet( prev );
                }
            }

            // if not in cache, must compute
            if ( tset == null )
            {
                tset = FirstCore( (NFAState)transition0.target, chaseFollowTransitions );
                // save FIRST cache for transition 0 if rule call
                if ( !chaseFollowTransitions && transition0 is RuleClosureTransition )
                {
                    _firstCache[(NFAState)transition0.target] = tset;
                }
            }

            // did we fall off the end?
            if ( _grammar.type != GrammarType.Lexer && tset.Member( Label.EOR_TOKEN_TYPE ) )
            {
                if ( transition0 is RuleClosureTransition )
                {
                    // we called a rule that found the end of the rule.
                    // That means the rule is nullable and we need to
                    // keep looking at what follows the rule ref.  E.g.,
                    // a : b A ; where b is nullable means that LOOK(a)
                    // should include A.
                    RuleClosureTransition ruleInvocationTrans =
                        (RuleClosureTransition)transition0;
                    // remove the EOR and get what follows
                    //tset.remove(Label.EOR_TOKEN_TYPE);
                    NFAState following = (NFAState)ruleInvocationTrans.followState;
                    LookaheadSet fset = FirstCore( following, chaseFollowTransitions );
                    fset.OrInPlace( tset ); // tset cached; or into new set
                    fset.Remove( Label.EOR_TOKEN_TYPE );
                    tset = fset;
                }
            }

            Transition transition1 = s.transition[1];
            if ( transition1 != null )
            {
                LookaheadSet tset1 =
                    FirstCore( (NFAState)transition1.target, chaseFollowTransitions );
                tset1.OrInPlace( tset ); // tset cached; or into new set
                tset = tset1;
            }

            return tset;
        }
示例#14
0
        protected virtual int DetectConfoundingPredicatesCore( NFAState s,
                                                   Rule enclosingRule,
                                                   bool chaseFollowTransitions )
        {
            //[email protected]("_detectNonAutobacktrackPredicates("+s+")");
            if ( !chaseFollowTransitions && s.IsAcceptState )
            {
                if ( _grammar.type == GrammarType.Lexer )
                {
                    // FOLLOW makes no sense (at the moment!) for lexical rules.
                    // assume all char can follow
                    return DETECT_PRED_NOT_FOUND;
                }
                return DETECT_PRED_EOR;
            }

            if ( _lookBusy.Contains( s ) )
            {
                // return a copy of an empty set; we may modify set inline
                return DETECT_PRED_NOT_FOUND;
            }
            _lookBusy.Add( s );

            Transition transition0 = s.transition[0];
            if ( transition0 == null )
            {
                return DETECT_PRED_NOT_FOUND;
            }

            if ( !( transition0.label.IsSemanticPredicate ||
                   transition0.label.IsEpsilon ) )
            {
                return DETECT_PRED_NOT_FOUND;
            }

            if ( transition0.label.IsSemanticPredicate )
            {
                //[email protected]("pred "+transition0.label);
                SemanticContext ctx = transition0.label.SemanticContext;
                SemanticContext.Predicate p = (SemanticContext.Predicate)ctx;
                if ( p.predicateAST.Type != ANTLRParser.BACKTRACK_SEMPRED )
                {
                    return DETECT_PRED_FOUND;
                }
            }

            /*
            if ( transition0.label.isSemanticPredicate() ) {
                [email protected]("pred "+transition0.label);
                SemanticContext ctx = transition0.label.getSemanticContext();
                SemanticContext.Predicate p = (SemanticContext.Predicate)ctx;
                // if a non-syn-pred found not in enclosingRule, say we found one
                if ( p.predicateAST.getType() != ANTLRParser.BACKTRACK_SEMPRED &&
                     !p.predicateAST.enclosingRuleName.equals(enclosingRule.name) )
                {
                    [email protected]("found pred "+p+" not in "+enclosingRule.name);
                    return DETECT_PRED_FOUND;
                }
            }
            */

            int result = DetectConfoundingPredicatesCore( (NFAState)transition0.target,
                                                      enclosingRule,
                                                      chaseFollowTransitions );
            if ( result == DETECT_PRED_FOUND )
            {
                return DETECT_PRED_FOUND;
            }

            if ( result == DETECT_PRED_EOR )
            {
                if ( transition0 is RuleClosureTransition )
                {
                    // we called a rule that found the end of the rule.
                    // That means the rule is nullable and we need to
                    // keep looking at what follows the rule ref.  E.g.,
                    // a : b A ; where b is nullable means that LOOK(a)
                    // should include A.
                    RuleClosureTransition ruleInvocationTrans =
                        (RuleClosureTransition)transition0;
                    NFAState following = (NFAState)ruleInvocationTrans.followState;
                    int afterRuleResult =
                        DetectConfoundingPredicatesCore( following,
                                                     enclosingRule,
                                                     chaseFollowTransitions );
                    if ( afterRuleResult == DETECT_PRED_FOUND )
                    {
                        return DETECT_PRED_FOUND;
                    }
                }
            }

            Transition transition1 = s.transition[1];
            if ( transition1 != null )
            {
                int t1Result =
                    DetectConfoundingPredicatesCore( (NFAState)transition1.target,
                                                 enclosingRule,
                                                 chaseFollowTransitions );
                if ( t1Result == DETECT_PRED_FOUND )
                {
                    return DETECT_PRED_FOUND;
                }
            }

            return DETECT_PRED_NOT_FOUND;
        }
示例#15
0
 public LookaheadSet Look( NFAState s )
 {
     if ( NFAToDFAConverter.debug )
     {
         Console.Out.WriteLine( "> LOOK(" + s + ")" );
     }
     _lookBusy.Clear();
     LookaheadSet look = FirstCore( s, true );
     // FOLLOW makes no sense (at the moment!) for lexical rules.
     if ( _grammar.type != GrammarType.Lexer && look.Member( Label.EOR_TOKEN_TYPE ) )
     {
         // avoid altering FIRST reset as it is cached
         LookaheadSet f = Follow( s.enclosingRule );
         f.OrInPlace( look );
         f.Remove( Label.EOR_TOKEN_TYPE );
         look = f;
         //look.orInPlace(FOLLOW(s.enclosingRule));
     }
     else if ( _grammar.type == GrammarType.Lexer && look.Member( Label.EOT ) )
     {
         // if this has EOT, lookahead is all char (all char can follow rule)
         //look = new LookaheadSet(Label.EOT);
         look = new LookaheadSet( IntervalSet.COMPLETE_SET );
     }
     if ( NFAToDFAConverter.debug )
     {
         Console.Out.WriteLine( "< LOOK(" + s + ")=" + look.ToString( _grammar ) );
     }
     return look;
 }
示例#16
0
 /** Return predicate expression found via epsilon edges from s.  Do
  *  not look into other rules for now.  Do something simple.  Include
  *  backtracking synpreds.
  */
 public SemanticContext GetPredicates( NFAState altStartState )
 {
     _lookBusy.Clear();
     return GetPredicatesCore( altStartState, altStartState );
 }
示例#17
0
 /** From an NFA state, s, find the set of all labels reachable from s.
  *  Used to compute follow sets for error recovery.  Never computes
  *  a FOLLOW operation.  FIRST stops at end of rules, returning EOR, unless
  *  invoked from another rule.  I.e., routine properly handles
  *
  *     a : b A ;
  *
  *  where b is nullable.
  *
  *  We record with EOR_TOKEN_TYPE if we hit the end of a rule so we can
  *  know at runtime (when these sets are used) to start walking up the
  *  follow chain to compute the real, correct follow set (as opposed to
  *  the FOLLOW, which is a superset).
  *
  *  This routine will only be used on parser and tree parser grammars.
  */
 public LookaheadSet First( NFAState s )
 {
     //[email protected]("> FIRST("+s.enclosingRule.name+") in rule "+s.enclosingRule);
     _lookBusy.Clear();
     LookaheadSet look = FirstCore( s, false );
     //[email protected]("< FIRST("+s.enclosingRule.name+") in rule "+s.enclosingRule+"="+look.toString(this.grammar));
     return look;
 }
示例#18
0
 public virtual int AssignDecisionNumber( NFAState state )
 {
     decisionCount++;
     state.DecisionNumber = decisionCount;
     return decisionCount;
 }
示例#19
0
文件: NFA.cs 项目: ymf1/webgrease
 public void AddState(NFAState state)
 {
     grammar.composite.AddState(state);
 }
示例#20
0
 /** Get the ith alternative (1..n) from a decision; return null when
  *  an invalid alt is requested.  I must count in to find the right
  *  alternative number.  For (A|B), you get NFA structure (roughly):
  *
  *  o->o-A->o
  *  |
  *  o->o-B->o
  *
  *  This routine returns the leftmost state for each alt.  So alt=1, returns
  *  the upperleft most state in this structure.
  */
 public virtual NFAState GetNFAStateForAltOfDecision( NFAState decisionState, int alt )
 {
     if ( decisionState == null || alt <= 0 )
     {
         return null;
     }
     int n = 1;
     NFAState p = decisionState;
     while ( p != null )
     {
         if ( n == alt )
         {
             return p;
         }
         n++;
         Transition next = p.transition[1];
         p = null;
         if ( next != null )
         {
             p = (NFAState)next.Target;
         }
     }
     return null;
 }
示例#21
0
        // output list of NFA states
        /** Given a sample input sequence, you usually would like to know the
         *  path taken through the NFA.  Return the list of NFA states visited
         *  while matching a list of labels.  This cannot use the usual
         *  interpreter, which does a deterministic walk.  We need to be able to
         *  take paths that are turned off during nondeterminism resolution. So,
         *  just do a depth-first walk traversing edges labeled with the current
         *  label.  Return true if a path was found emanating from state s.
         */
        protected virtual bool GetNFAPath( NFAState s,     // starting where?
                                     int labelIndex, // 0..labels.size()-1
                                     IList<Label> labels,    // input sequence
                                     IList<NFAState> path )
        {
            // track a visit to state s at input index labelIndex if not seen
            string thisStateKey = GetStateLabelIndexKey( s.StateNumber, labelIndex );
            if ( _statesVisitedAtInputDepth.Contains( thisStateKey ) )
            {
                /*
                [email protected]("### already visited "+s.stateNumber+" previously at index "+
                               labelIndex);
                */
                return false;
            }
            _statesVisitedAtInputDepth.Add( thisStateKey );

            /*
            [email protected]("enter state "+s.stateNumber+" visited states: "+
                               statesVisitedAtInputDepth);
            */

            // pick the first edge whose target is in states and whose
            // label is labels[labelIndex]
            for ( int i = 0; i < s.NumberOfTransitions; i++ )
            {
                Transition t = s.transition[i];
                NFAState edgeTarget = (NFAState)t.Target;
                Label label = (Label)labels[labelIndex];
                /*
                [email protected](s.stateNumber+"-"+
                                   t.label.toString(dfa.nfa.Grammar)+"->"+
                                   edgeTarget.stateNumber+" =="+
                                   label.toString(dfa.nfa.Grammar)+"?");
                */
                if ( t.Label.IsEpsilon || t.Label.IsSemanticPredicate )
                {
                    // nondeterministically backtrack down epsilon edges
                    path.Add( edgeTarget );
                    bool found =
                        GetNFAPath( edgeTarget, labelIndex, labels, path );
                    if ( found )
                    {
                        _statesVisitedAtInputDepth.Remove( thisStateKey );
                        return true; // return to "calling" state
                    }
                    path.RemoveAt( path.Count - 1 ); // remove; didn't work out
                    continue; // look at the next edge
                }
                if ( t.Label.Matches( label ) )
                {
                    path.Add( edgeTarget );
                    /*
                    [email protected]("found label "+
                                       t.label.toString(dfa.nfa.Grammar)+
                                       " at state "+s.stateNumber+"; labelIndex="+labelIndex);
                    */
                    if ( labelIndex == labels.Count - 1 )
                    {
                        // found last label; done!
                        _statesVisitedAtInputDepth.Remove( thisStateKey );
                        return true;
                    }
                    // otherwise try to match remaining input
                    bool found =
                        GetNFAPath( edgeTarget, labelIndex + 1, labels, path );
                    if ( found )
                    {
                        _statesVisitedAtInputDepth.Remove( thisStateKey );
                        return true;
                    }
                    /*
                    [email protected]("backtrack; path from "+s.stateNumber+"->"+
                                       t.label.toString(dfa.nfa.Grammar)+" didn't work");
                    */
                    path.RemoveAt( path.Count - 1 ); // remove; didn't work out
                    continue; // keep looking for a path for labels
                }
            }
            //[email protected]("no epsilon or matching edge; removing "+thisStateKey);
            // no edge was found matching label; is ok, some state will have it
            _statesVisitedAtInputDepth.Remove( thisStateKey );
            return false;
        }
示例#22
0
 public virtual LookaheadSet Look( NFAState s )
 {
     return ll1Analyzer.Look( s );
 }
示例#23
0
 public NFAContext( NFAContext parent, NFAState invokingState )
 {
     this.parent = parent;
     this.invokingState = invokingState;
     if ( invokingState != null )
     {
         this._cachedHashCode = invokingState.stateNumber;
     }
     if ( parent != null )
     {
         this._cachedHashCode += parent._cachedHashCode;
     }
 }
示例#24
0
        /** Add an NFA configuration to this DFA node.  Add uniquely
         *  an NFA state/alt/syntactic&semantic context (chain of invoking state(s)
         *  and semantic predicate contexts).
         *
         *  I don't see how there could be two configurations with same
         *  state|alt|synCtx and different semantic contexts because the
         *  semantic contexts are computed along the path to a particular state
         *  so those two configurations would have to have the same predicate.
         *  Nonetheless, the addition of configurations is unique on all
         *  configuration info.  I guess I'm saying that syntactic context
         *  implies semantic context as the latter is computed according to the
         *  former.
         *
         *  As we add configurations to this DFA state, track the set of all possible
         *  transition labels so we can simply walk it later rather than doing a
         *  loop over all possible labels in the NFA.
         */
        public virtual void AddNFAConfiguration( NFAState state, NFAConfiguration c )
        {
            if ( nfaConfigurations.Contains( c ) )
            {
                return;
            }

            nfaConfigurations.Add( c );

            // track min alt rather than compute later
            if ( c.alt < minAltInConfigurations )
            {
                minAltInConfigurations = c.alt;
            }

            if ( c.semanticContext != SemanticContext.EmptySemanticContext )
            {
                _atLeastOneConfigurationHasAPredicate = true;
            }

            // update hashCode; for some reason using context.hashCode() also
            // makes the GC take like 70% of the CPU and is slow!
            _cachedHashCode += c.state + c.alt;

            // update reachableLabels
            // We're adding an NFA state; check to see if it has a non-epsilon edge
            if ( state.transition[0] != null )
            {
                Label label = state.transition[0].label;
                if ( !( label.IsEpsilon || label.IsSemanticPredicate ) )
                {
                    // this NFA state has a non-epsilon edge, track for fast
                    // walking later when we do reach on this DFA state we're
                    // building.
                    configurationsWithLabeledEdges.Add( c );
                    if ( state.transition[1] == null )
                    {
                        // later we can check this to ignore o-A->o states in closure
                        c.singleAtomTransitionEmanating = true;
                    }
                    AddReachableLabel( label );
                }
            }
        }
示例#25
0
        private static bool HasOneOrMoreEpsilonTransitionOnly(NFAState state)
        {
            for (int t = 0; t < state.NumberOfTransitions; t++)
            {
                Transition transition = state.transition[t];
                if (!transition.IsEpsilon)
                    return false;
            }

            return state.NumberOfTransitions > 0;
        }
示例#26
0
 protected DFA( int decisionNumber, NFAState decisionStartState )
 {
     this._probe = new DecisionProbe(this);
     this._decisionNumber = decisionNumber;
     this._decisionNFAStartState = decisionStartState;
     this._nfa = decisionStartState.nfa;
     this._numberOfAlts = Nfa.Grammar.GetNumberOfAltsForDecisionNFA( decisionStartState );
     //setOptions( nfa.grammar.getDecisionOptions(getDecisionNumber()) );
     this._altToAcceptState = new DFAState[NumberOfAlts + 1];
     this._unreachableAlts = new List<int>(Enumerable.Range(1, NumberOfAlts));
 }
示例#27
0
 private int NumberOfIncomingTransition(NFAState state)
 {
     return _links.Count(i => i.Key.Value.Target == state);
 }
示例#28
0
 /** For reference to rule r, build
  *
  *  o-e->(r)  o
  *
  *  where (r) is the start of rule r and the trailing o is not linked
  *  to from rule ref state directly (it's done thru the transition(0)
  *  RuleClosureTransition.
  *
  *  If the rule r is just a list of tokens, it's block will be just
  *  a set on an edge o->o->o-set->o->o->o, could inline it rather than doing
  *  the rule reference, but i'm not doing this yet as I'm not sure
  *  it would help much in the NFA->DFA construction.
  *
  *  TODO add to codegen: collapse alt blks that are sets into single matchSet
  */
 public virtual StateCluster BuildRuleRef( Rule refDef, NFAState ruleStart )
 {
     //System.Console.Out.WriteLine( "building ref to rule " + nfa.grammar.name + "." + refDef.name );
     NFAState left = NewState();
     //left.Description = "ref to " + ruleStart.Description;
     NFAState right = NewState();
     //right.Description = "NFAState following ref to " + ruleStart.Description;
     Transition e = new RuleClosureTransition( refDef, ruleStart, right );
     left.AddTransition( e );
     StateCluster g = new StateCluster( left, right );
     return g;
 }
示例#29
0
        /** Given a sample input sequence, you usually would like to know the
         *  path taken through the NFA.  Return the list of NFA states visited
         *  while matching a list of labels.  This cannot use the usual
         *  interpreter, which does a deterministic walk.  We need to be able to
         *  take paths that are turned off during nondeterminism resolution. So,
         *  just do a depth-first walk traversing edges labeled with the current
         *  label.  Return true if a path was found emanating from state s.
         */
        protected virtual bool GetNFAPath(NFAState s,            // starting where?
                                          int labelIndex,        // 0..labels.size()-1
                                          IList <Label> labels,  // input sequence
                                          IList <NFAState> path) // output list of NFA states
        {
            // track a visit to state s at input index labelIndex if not seen
            string thisStateKey = GetStateLabelIndexKey(s.StateNumber, labelIndex);

            if (_statesVisitedAtInputDepth.Contains(thisStateKey))
            {
                /*
                 * [email protected]("### already visited "+s.stateNumber+" previously at index "+
                 *             labelIndex);
                 */
                return(false);
            }
            _statesVisitedAtInputDepth.Add(thisStateKey);

            /*
             * [email protected]("enter state "+s.stateNumber+" visited states: "+
             *                 statesVisitedAtInputDepth);
             */

            // pick the first edge whose target is in states and whose
            // label is labels[labelIndex]
            for (int i = 0; i < s.NumberOfTransitions; i++)
            {
                Transition t          = s.transition[i];
                NFAState   edgeTarget = (NFAState)t.Target;
                Label      label      = (Label)labels[labelIndex];

                /*
                 * [email protected](s.stateNumber+"-"+
                 *                 t.label.toString(dfa.nfa.Grammar)+"->"+
                 *                 edgeTarget.stateNumber+" =="+
                 *                 label.toString(dfa.nfa.Grammar)+"?");
                 */
                if (t.Label.IsEpsilon || t.Label.IsSemanticPredicate)
                {
                    // nondeterministically backtrack down epsilon edges
                    path.Add(edgeTarget);
                    bool found =
                        GetNFAPath(edgeTarget, labelIndex, labels, path);
                    if (found)
                    {
                        _statesVisitedAtInputDepth.Remove(thisStateKey);
                        return(true);              // return to "calling" state
                    }
                    path.RemoveAt(path.Count - 1); // remove; didn't work out
                    continue;                      // look at the next edge
                }
                if (t.Label.Matches(label))
                {
                    path.Add(edgeTarget);

                    /*
                     * [email protected]("found label "+
                     *                 t.label.toString(dfa.nfa.Grammar)+
                     *                 " at state "+s.stateNumber+"; labelIndex="+labelIndex);
                     */
                    if (labelIndex == labels.Count - 1)
                    {
                        // found last label; done!
                        _statesVisitedAtInputDepth.Remove(thisStateKey);
                        return(true);
                    }
                    // otherwise try to match remaining input
                    bool found =
                        GetNFAPath(edgeTarget, labelIndex + 1, labels, path);
                    if (found)
                    {
                        _statesVisitedAtInputDepth.Remove(thisStateKey);
                        return(true);
                    }

                    /*
                     * [email protected]("backtrack; path from "+s.stateNumber+"->"+
                     *                 t.label.toString(dfa.nfa.Grammar)+" didn't work");
                     */
                    path.RemoveAt(path.Count - 1); // remove; didn't work out
                    continue;                      // keep looking for a path for labels
                }
            }
            //[email protected]("no epsilon or matching edge; removing "+thisStateKey);
            // no edge was found matching label; is ok, some state will have it
            _statesVisitedAtInputDepth.Remove(thisStateKey);
            return(false);
        }
示例#30
0
 /** set up an NFA NFAState that will yield eof tokens or,
  *  in the case of a lexer grammar, an EOT token when the conversion
  *  hits the end of a rule.
  */
 private void BuildEofState( NFAState endNFAState )
 {
     NFAState end = NewState();
     int label = Label.EOF;
     if ( _nfa.Grammar.type == GrammarType.Lexer )
     {
         label = Label.EOT;
         end.IsEOTTargetState = true;
     }
     //System.Console.Out.WriteLine( "build " + nfa.grammar.getTokenDisplayName( label ) +
     //                              " loop on end of state " + endNFAState.Description +
     //                              " to state " + end.stateNumber );
     Transition toEnd = new Transition( label, end );
     endNFAState.AddTransition( toEnd );
 }
示例#31
0
        /** From a set of edgeset->list-of-alts mappings, create a DFA
         *  that uses syn preds for all |list-of-alts|>1.
         */
        public LL1DFA(int decisionNumber, NFAState decisionStartState, MultiMap <IntervalSet, int> edgeMap)
            : base(decisionNumber, decisionStartState)
        {
            DFAState s0 = NewState();

            StartState = s0;
            UnreachableAlts.Clear();
            foreach (var edgeVar in edgeMap)
            {
                IntervalSet edge = edgeVar.Key;
                IList <int> alts = edgeVar.Value;
                alts = alts.OrderBy(i => i).ToList();
                //Collections.sort( alts ); // make sure alts are attempted in order
                //[email protected](edge+" -> "+alts);
                DFAState s = NewState();
                s.LookaheadDepth = 1;
                Label e = GetLabelForSet(edge);
                s0.AddTransition(s, e);
                if (alts.Count == 1)
                {
                    s.IsAcceptState = true;
                    int alt = alts[0];
                    SetAcceptState(alt, s);
                    s.CachedUniquelyPredicatedAlt = alt;
                }
                else
                {
                    // resolve with syntactic predicates.  Add edges from
                    // state s that test predicates.
                    s.IsResolvedWithPredicates = true;
                    for (int i = 0; i < alts.Count; i++)
                    {
                        int alt = (int)alts[i];
                        s.CachedUniquelyPredicatedAlt = NFA.INVALID_ALT_NUMBER;
                        DFAState predDFATarget = GetAcceptState(alt);
                        if (predDFATarget == null)
                        {
                            predDFATarget = NewState(); // create if not there.
                            predDFATarget.IsAcceptState = true;
                            predDFATarget.CachedUniquelyPredicatedAlt = alt;
                            SetAcceptState(alt, predDFATarget);
                        }
                        // add a transition to pred target from d

                        /*
                         * int walkAlt =
                         *  decisionStartState.translateDisplayAltToWalkAlt(alt);
                         * NFAState altLeftEdge = nfa.grammar.getNFAStateForAltOfDecision(decisionStartState, walkAlt);
                         * NFAState altStartState = (NFAState)altLeftEdge.transition[0].target;
                         * SemanticContext ctx = nfa.grammar.ll1Analyzer.getPredicates(altStartState);
                         * [email protected]("sem ctx = "+ctx);
                         * if ( ctx == null ) {
                         *  ctx = new SemanticContext.TruePredicate();
                         * }
                         * s.addTransition(predDFATarget, new Label(ctx));
                         */
                        SemanticContext.Predicate synpred =
                            GetSynPredForAlt(decisionStartState, alt);
                        if (synpred == null)
                        {
                            synpred = new SemanticContext.TruePredicate();
                        }
                        s.AddTransition(predDFATarget, new PredicateLabel(synpred));
                    }
                }
            }
            //[email protected]("dfa for preds=\n"+this);
        }
示例#32
0
文件: NFA.cs 项目: bszafko/antlrcs
 public void AddState( NFAState state )
 {
     grammar.composite.AddState( state );
 }
 protected virtual void AddFollowTransition( string ruleName, NFAState following )
 {
     //System.Console.Out.WriteLine( "adding follow link to rule " + ruleName );
     // find last link in FOLLOW chain emanating from rule
     Rule r = grammar.GetRule( ruleName );
     NFAState end = r.StopState;
     while ( end.GetTransition( 1 ) != null )
     {
         end = (NFAState)end.GetTransition( 1 ).Target;
     }
     if ( end.GetTransition( 0 ) != null )
     {
         // already points to a following node
         // gotta add another node to keep edges to a max of 2
         NFAState n = factory.NewState();
         Transition e = new Transition( Label.EPSILON, n );
         end.AddTransition( e );
         end = n;
     }
     Transition followEdge = new Transition( Label.EPSILON, following );
     end.AddTransition( followEdge );
 }