Source/NFX/CodeAnalysis/PatternSearch.cs
/// <summary>
/// Makes finite state machine fed from IEnumerable(Token)
/// </summary>
/// <typeparam name="TToken">Concrete language-typed token</typeparam>
/// <param name="tokens">Token enumerable</param>
/// <param name="onlyPrimary">Sets filter to consider only primary language tokens (skip comments, directives, etc.)</param>
/// <param name="state">Machine's state which will be allocated if null passed</param>
/// <param name="predicates">Predicates that supply machine state transition instructions</param>
/// <returns>Resulting token fetched by FSMI.Take instruction or null</returns>
Makes finite state machine fed from IEnumerable(Token)
Makes finite state machine fed from IEnumerable ( Token )
public static TToken LazyFSM<TToken>(this IEnumerable<TToken> tokens,
                                        bool onlyPrimary,
                                        ref LazyFSMState<TToken> state,
                                        params LazyFSMPredicate<TToken>[] predicates) where TToken : Token
       {
          var first = true;
          var pidx = 0;
          TToken result = null;
          var en = tokens.GetEnumerator();
          if (state==null)
            state = new LazyFSMState<TToken>();
          state.m_Tokens = tokens;
          state.m_CurrentTokenIndex = -1;
          state.m_PatternTokenLength = -1;
          state.m_OnlyPrimary = onlyPrimary;
          var dontMove = false;
          while(pidx<predicates.Length)
          {
            if (dontMove)
                dontMove = false;
            else
            {
                if (!en.MoveNext()) break;
                state.m_CurrentTokenIndex++;
                state.m_PatternTokenLength++;
            }
            TToken token = en.Current;
            if (token.IsEOF) break;
            if  (!onlyPrimary || token.IsPrimary || first)
            {
               first = false;
               state.m_CurrentToken = token;
               var action = predicates[pidx](state, token);
               switch(action)
               {
                 case FSMI.Loop: break;
                 case FSMI.Abort: return null;
                 case FSMI.Advance:  {
                                        pidx++;
                                        break;
                                     }
                 case FSMI.AdvanceOnSameToken:  {
                                        pidx++;
                                        dontMove = true;
                                        break;
                                     }
                 case FSMI.Take:
                                    {
                                    result = token;
                                    pidx++;
                                    break;
                                    }
                 case FSMI.TakeAndComplete:  return token;
                 case FSMI.Complete: return result;
                 default: return null;
               }
            }
          }
          return result;
       }
public static TToken LazyFSM < TToken > ( this IEnumerable < TToken > tokens , bool onlyPrimary , ref LazyFSMState < TToken > state , params LazyFSMPredicate < TToken > [ ] predicates ) where TToken : Token { var first = true ; var pidx = 0 ; TToken result = null ; var en = tokens . GetEnumerator ( ) ; if ( state == null ) state = new LazyFSMState < TToken > ( ) ; state . m_Tokens = tokens ; state . m_CurrentTokenIndex = - 1 ; state . m_PatternTokenLength = - 1 ; state . m_OnlyPrimary = onlyPrimary ; var dontMove = false ; while ( pidx < predicates . Length ) { if ( dontMove ) dontMove = false ; else { if ( ! en . MoveNext ( ) ) break ; state . m_CurrentTokenIndex ++ ; state . m_PatternTokenLength ++ ; } TToken token = en . Current ; if ( token . IsEOF ) break ; if ( ! onlyPrimary || token . IsPrimary || first ) { first = false ; state . m_CurrentToken = token ; var action = predicates [ pidx ] ( state , token ) ; switch ( action ) { case FSMI . Loop : break ; case FSMI . Abort : return null ; case FSMI . Advance : { pidx ++ ; break ; } case FSMI . AdvanceOnSameToken : { pidx ++ ; dontMove = true ; break ; } case FSMI . Take : { result = token ; pidx ++ ; break ; } case FSMI . TakeAndComplete : return token ; case FSMI . Complete : return result ; default : return null ; } } } return result ; }
Makes finite state machine fed from IEnumerable(Token)
Makes finite state machine fed from IEnumerable ( Token )
//while
Resulting token fetched by FSMI.Take instruction or null
Resulting token fetched by FSMI . Take instruction or null
IEnumerable<TToken>
this
onlyPrimary
bool
Sets filter to consider only primary language tokens (skip comments, directives, etc.)
Sets filter to consider only primary language tokens ( skip comments directives etc . )
LazyFSMState<TToken>
ref
tokens
None
state
Machine's state which will be allocated if null passed
Machine ' s state which will be allocated if null passed
predicates
Predicates that supply machine state transition instructions
Predicates that supply machine state transition instructions
typeparam
Concrete language-typed token
Concrete language - typed token