private IRegexFSMTransition <T> GenerateNFATransitionFromRegexPreviousMatch(
            RegexPreviousMatch <T> previousMatch,
            IRegexNFA <T> nfa,
            IRegexNFAState <T> state
            )
        {
            var predicateTransition = new RegexFSMPredicateTransition <T>((sender, args) =>
            {
                if (args.FirstOrDefault() is IRegexFSM <T> fsm)
                {
                    var lastMatch = fsm.Matches?.LastOrDefault();
                    if (lastMatch == null)
                    {
                        // 没有上一个匹配。
                        return(true);
                    }
                    else
                    {
                        // 状态机当前索引与上一个匹配的结尾索引相邻。
                        return(fsm.Index == lastMatch.Index + lastMatch.Length);
                    }
                }
                else
                {
                    return(false);
                }
            });

            nfa.AttachTransition(state, predicateTransition);

            return(predicateTransition);
        }
 protected virtual IRegexFSMTransition <T> GenerateNFATransitionFromIRegexAnchorPoint(
     IRegexAnchorPoint <T> anchorPoint,
     IRegexNFA <T> nfa,
     IRegexNFAState <T> state
     )
 {
     if (anchorPoint is RegexZeroLengthObject <T> zeroLength)
     {
         return(this.GenerateNFATransitionFromRegexZeroLengthObject(zeroLength, nfa, state));
     }
     else if (anchorPoint is RegexStartBorder <T> startBorder)
     {
         return(this.GenerateNFATransitionFromRegexStartBorder(startBorder, nfa, state));
     }
     else if (anchorPoint is RegexEndBorder <T> endBorder)
     {
         return(this.GenerateNFATransitionFromRegexEndBorder(endBorder, nfa, state));
     }
     else if (anchorPoint is RegexPreviousMatch <T> previousMatch)
     {
         return(this.GenerateNFATransitionFromRegexPreviousMatch(previousMatch, nfa, state));
     }
     else
     {
         throw new NotSupportedException();
     }
 }
        private IRegexFSMTransition <T> GenerateNFATransitionFromRegexZeroLengthObject(
            RegexZeroLengthObject <T> zeroLength,
            IRegexNFA <T> nfa,
            IRegexNFAState <T> state
            )
        {
            const string PROGRESS_SERVICE_KEY = "PROGRESS_SERVICE";
            const string PROGRESS_KEY         = "TIMEPOINT";

            IRegexNFAState <T> nextState = state;

            RegexFSMPredicateTransition <T> predicateTransition;

            predicateTransition = new RegexFSMPredicateTransition <T>((sender, args) =>
            {
                if (args.FirstOrDefault() is IRegexFSM <T> fsm)
                {
                    var progressService = fsm.GetService <RegexFSM <T> .ProgressService>();
                    var progress        = progressService.GetProgress();
                    fsm.UserData[PROGRESS_SERVICE_KEY] = progressService;
                    fsm.UserData[PROGRESS_KEY]         = progress;

                    return(true);
                }
                return(false);
            });
            nfa.AttachTransition(nextState, predicateTransition);
            nextState = this.contextInfo.ActivateRegexNFAState();
            nfa.SetTarget(predicateTransition, nextState);

            var transition = this.GenerateNFATransitionFromRegexObject(zeroLength.InnerRegex, nfa, nextState);

            nextState = this.contextInfo.ActivateRegexNFAState();
            nfa.SetTarget(transition, nextState);

            predicateTransition = new RegexFSMPredicateTransition <T>((sender, args) =>
            {
                if (args.FirstOrDefault() is IRegexFSM <T> fsm)
                {
                    var progressService = (RegexFSM <T> .ProgressService)fsm.UserData[PROGRESS_SERVICE_KEY];
                    var progress        = (RegexFSM <T> .ProgressService.Progress)fsm.UserData[PROGRESS_KEY];
                    progressService.SetProgress(progress);

                    return(true);
                }
                return(false);
            });

            return(predicateTransition);
        }
        private IRegexFSMTransition <T> GenerateNFATransitionFromRegexEndBorder(
            RegexEndBorder <T> endBorder,
            IRegexNFA <T> nfa,
            IRegexNFAState <T> state
            )
        {
            var predicateTransition = new RegexFSMPredicateTransition <T>((sender, args) =>
                                                                          (args.FirstOrDefault() is IRegexFSM <T> fsm) &&
                                                                          fsm.Index == fsm.Inputs.Count()
                                                                          );

            nfa.AttachTransition(state, predicateTransition);

            return(predicateTransition);
        }
 protected virtual IRegexFSMTransition <T> GenerateNFATransitionFromRegexObject(
     RegexObject <T> regex,
     IRegexNFA <T> nfa,
     IRegexNFAState <T> state
     )
 {
     if (regex is IRegexAnchorPoint <T> anchorPoint)
     {
         return(this.GenerateNFATransitionFromIRegexAnchorPoint(anchorPoint, nfa, state));
     }
     else if (regex is RegexGroup <T> group)
     {
         return(this.GenerateNFATransitionFromRegexGroup(group, nfa, state));
     }
     else if (regex is RegexGroupReference <T> groupReference)
     {
         return(this.GenerateNFATransitionFromRegexGroupReference(groupReference, nfa, state));
     }
     else if (regex is RegexMultiBranch <T> multiBranch)
     {
         return(this.GenerateNFATransitionFromRegexMultiBranch(multiBranch, nfa, state));
     }
     else if (regex is RegexCondition <T> condition)
     {
         return(this.GenerateNFATransitionFromRegexCondition(condition, nfa, state));
     }
     else if (regex is RegexRepeat <T> repeat)
     {
         return(this.GenerateNFATransitionFromRegexRepeat(repeat, nfa, state));
     }
     else if (regex is RegexNonGreedyRepeat <T> nonGreedyRepeat)
     {
         return(this.GenerateNFATransitionFromRegexNonGreedyRepeat(nonGreedyRepeat, nfa, state));
     }
     else if (regex is RegexSeries <T> series)
     {
         return(this.GenerateNFATransitionFromRegexSeries(series, nfa, state));
     }
     else if (regex is RegexParallels <T> parallels)
     {
         return(this.GenerateNFATransitionFromRegexParallels(parallels, nfa, state));
     }
     else
     {
         throw new NotSupportedException(string.Format("不支持的正则类型:{0}", regex.GetType()));
     }
 }
        public IRegexFSM <T> GenerateRegexFSMFromRegexObject(RegexObject <T> regex, RegexOptions options)
        {
            if (regex == null)
            {
                throw new ArgumentNullException(nameof(regex));
            }

            IRegexNFA <T>      nfa        = this.contextInfo.ActivateRegexNFA();
            IRegexNFAState <T> startState = this.contextInfo.ActivateRegexNFAState();

            nfa.StartState = startState;

            IRegexFSMTransition <T> transition = this.GenerateNFATransitionFromRegexObject(regex, nfa, startState);
            IRegexNFAState <T>      endState   = this.contextInfo.ActivateRegexNFAState(true);

            nfa.SetTarget(transition, endState);

            return(nfa);
        }
        protected virtual IRegexFSMTransition <T> GenerateNFATransitionFromRegexGroupReference(
            RegexGroupReference <T> groupReference,
            IRegexNFA <T> nfa,
            IRegexNFAState <T> state
            )
        {
            RegexGroup <T> group;

            if (groupReference.IsDetermined)
            {
                group = groupReference.Group;
            }
            else
            {
                IRegexFSMEpsilonTransition <T> epsilonTransition = this.contextInfo.ActivateRegexFSMEpsilonTransition();

                var groups = this.regexGroups.Where(_group => _group.ID == groupReference.GroupID).ToArray();
                switch (groups.Length)
                {
                case 0:
                    //throw new InvalidOperationException("未找到引用的正则组。");
                    epsilonTransition = this.contextInfo.ActivateRegexFSMEpsilonTransition();
                    nfa.AttachTransition(state, epsilonTransition);
                    return(epsilonTransition);

                case 1:
                    group = groups[0];
                    break;

                default:
                    group = new RegexGroup <T>(
                        groups.Select(_group => _group.InnerRegex).UnionMany()
                        );
                    break;
                    //throw new InvalidOperationException("找到多个重复 ID 的正则组。");
                    //epsilonTransition = this.contextInfo.ActivateRegexNFAEpsilonTransition();
                    //nfa.AttachTransition(state, epsilonTransition);
                    //return epsilonTransition;
                }
            }

            IRegexNFAState <T> nextState = state;

            var lastCaptureReferenceTransition = new RegexFSMLastCaptureReferenceTransition <T>(group, group.ID, (sender, readerSource, handler, args) =>
            {
                if (args.FirstOrDefault() is IRegexFSM <T> fsm)
                {
                    if (fsm.TryGetLastCapture(sender.IDToken, sender.ID, out int start, out int length))
                    {
                        var progressService = fsm.GetService <RegexFSM <T> .ProgressService>();
                        var progress        = progressService.GetProgress();

                        foreach (var t in fsm.Inputs.Skip(start).Take(length))
                        {
                            if (!(readerSource.HasNext() && EqualityComparer <T> .Default.Equals(readerSource.Read(), t)))
                            {
                                progressService.SetProgress(progress);
                                return(false);
                            }
                        }

                        return(true);
                    }
                }