Ejemplo n.º 1
0
        /// <summary>
        /// Loops until token pattern match succeeds.
        /// This method matches using the same primary token filter as the parent match.
        /// Keeps state machine if match was found on the first token that follows the match
        /// </summary>
        public static FSMI LoopUntilAfterMatch <TToken>(this LazyFSMState <TToken> state,
                                                        params LazyFSMPredicate <TToken>[] predicates
                                                        ) where TToken : Token
        {
            if (state.m_SkipCount > 0)
            {
                state.m_SkipCount--;
                if (state.m_SkipCount == 0)
                {
                    return(FSMI.Advance);
                }
                return(FSMI.Loop);
            }

            var stream = state.Tokens;

            if (state.m_CurrentTokenIndex > 0)
            {
                stream = stream.Skip(state.m_CurrentTokenIndex);
            }

            LazyFSMState <TToken> subState = new LazyFSMState <TToken>();

            if (stream.LazyFSM(state.m_OnlyPrimary, ref subState, predicates) != null)
            {
                return(state.Skip(subState.m_PatternTokenLength - 1));
            }

            return(FSMI.Loop);
        }
Ejemplo n.º 2
0
        /// <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="predicates">Predicates that supply machine state transition instructions</param>
        /// <returns>Resulting token fetched by FSMI.Take instruction or null</returns>
        public static TToken LazyFSM <TToken>(this IEnumerable <TToken> tokens,
                                              bool onlyPrimary,
                                              params LazyFSMPredicate <TToken>[] predicates) where TToken : Token
        {
            LazyFSMState <TToken> state = null;

            return(tokens.LazyFSM <TToken>(onlyPrimary, ref state, predicates));
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Loops until token pattern match succeeds, conditionally considering only primary language tokens.
        /// Keeps state machine if match was found on the first matching token
        /// </summary>
        public static FSMI LoopUntilMatch <TToken>(this LazyFSMState <TToken> state,
                                                   bool onlyPrimary,
                                                   params LazyFSMPredicate <TToken>[] predicates
                                                   ) where TToken : Token
        {
            var stream = state.Tokens;

            if (state.m_CurrentTokenIndex > 0)
            {
                stream = stream.Skip(state.m_CurrentTokenIndex);
            }

            LazyFSMState <TToken> subState = new LazyFSMState <TToken>();

            return(stream.LazyFSM(onlyPrimary, ref subState, predicates) != null ? FSMI.AdvanceOnSameToken : FSMI.Loop);
        }
Ejemplo n.º 4
0
 /// <summary>
 /// Skips specified number of tokens by returning FSMI.Loop count times
 /// </summary>
 public static FSMI Skip <TToken>(this LazyFSMState <TToken> state,
                                  int count) where TToken : Token
 {
     if (count == 0)
     {
         return(FSMI.Advance);
     }
     if (count < 0)
     {
         throw new CodeAnalysisException("FSMI Skip(count) must be > 0");
     }
     if (state.m_SkipCount > 0)
     {
         state.m_SkipCount--;
         if (state.m_SkipCount == 0)
         {
             return(FSMI.Advance);
         }
         return(FSMI.Loop);
     }
     state.m_SkipCount = count;
     return(FSMI.Loop);
 }
Ejemplo n.º 5
0
        /// <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>
        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);
                    }
                }
            }//while

            return(result);
        }
Ejemplo n.º 6
0
 /// <summary>
 /// Loops until token pattern match succeeds, considering only primary language tokens.
 /// Keeps state machine if match was found on the first matching token
 /// </summary>
 public static FSMI LoopUntilMatch <TToken>(this LazyFSMState <TToken> state,
                                            params LazyFSMPredicate <TToken>[] predicates
                                            ) where TToken : Token
 {
     return(state.LoopUntilMatch(true, predicates));
 }