Esempio n. 1
0
        private bool Match(string input, int startIndex, out RichResult result)
        {
            result = new RichResult();
            var normalStateRecords = new List<StateInfo>();
            var extStateRecords = new List<ExtensionStateInfo>();
            var currentState = new StateInfo
            {
                Position = 0,
                Current = _dfa.StartState,
                MinAvaliableTransition = 0,
                Reason = StateInfo.SaveReason.Other
            };

            normalStateRecords.Add(currentState);

            while (!currentState.Current.IsFinalState)
            {
                bool found = false;
                var stateToSave = new StateInfo(currentState);
                for(int i = 0; i < currentState.Current.Output.Count; ++i)
                {
                    var transition = currentState.Current.Output[i];
                    switch (transition.TransitionType)
                    {
                        case Transition.Type.Chars:
                            var c = input[currentState.Position];
                            var range = transition.Range;
                            if (c >= range.Begin && c <= range.End)
                            {
                                currentState.Current = transition.End;
                                currentState.Position++;
                            }
                            else found = false;
                            break;
                        case Transition.Type.BeginString:
                            found = currentState.Position == 0;
                            break;
                        case Transition.Type.EndString:
                            found = currentState.Position == input.Length - 1;
                            break;
                        case Transition.Type.Nop:
                            found = true;
                            break;
                        case Transition.Type.Capture:
                            {
                                var captureRecord = new CaptureRecord
                                {
                                    CaptureIndex = transition.Capture,
                                    StartIndex = currentState.Position,
                                    MatchLength = -1
                                };
                                result.Records.Add(captureRecord);
                                var extStateInfo = new ExtensionStateInfo
                                {
                                    Position = currentState.Position,
                                    SavedTransition = transition
                                };
                                extStateRecords.Add(extStateInfo);
                                found = true;
                            }
                            break;
                        case Transition.Type.Match:
                            int index = 0;
                            foreach(var record in result.Records)
                            {
                                if(record.CaptureIndex == transition.Capture)
                                {
                                    if(record.MatchLength != -1 && (transition.Index == -1 || transition.Index == index))
                                    {
                                        if (input.Substring(record.StartIndex, record.MatchLength) == input.Substring(currentState.Position, record.MatchLength))
                                        {
                                            currentState.Position += record.MatchLength;
                                            found = true;
                                            break;
                                        }
                                    }
                                    else ++index;
                                }
                            }
                            break;
                        case Transition.Type.Positive:
                            {
                                var extStateInfo = new ExtensionStateInfo
                                {
                                    Position = currentState.Position,
                                    SavedTransition = transition
                                };

                                extStateRecords.Add(extStateInfo);
                                stateToSave.Reason = StateInfo.SaveReason.Positive;
                            }
                            break;
                        case Transition.Type.End:
                            var prevState = extStateRecords.Last();
                            extStateRecords.RemoveAt(extStateRecords.Count - 1);
                            switch(prevState.SavedTransition.TransitionType)
                            {
                                case Transition.Type.Capture:
                                    {
                                        var capture = result.Records[prevState.CaptureListIndex];
                                        capture.MatchLength = currentState.Position - prevState.Position;
                                        found = true;
                                    }
                                    break;
                                case Transition.Type.Positive:
                                    {
                                        //Positive 结束后,回到初始 Positive 状态。
                                        for(int j = normalStateRecords.Count - 1; j >=0; --j)
                                        {
                                            var state = normalStateRecords[j];
                                            if(state.Reason == StateInfo.SaveReason.Positive)
                                            {
                                                currentState.Position = state.Position;
                                                stateToSave.Position = state.Position;
                                                break;
                                            }
                                        }
                                        found = true;
                                    }
                                    break;
                                default:
                                    break;
                            }
                            break;
                        default:
                            break;
                    }
                    if (found)
                    {
                        //有一条边是可以过的。
                        var userData = (UserData)currentState.Current.UserData;
                        if (userData.ShouldBeSaved == true)
                        {
                            stateToSave.MinAvaliableTransition = i + 1;
                            normalStateRecords.Add(stateToSave);
                        }
                        currentState.Current = transition.End;
                        currentState.MinAvaliableTransition = 0;
                    }
                }
                //试过了所有的边,都没有找到,回溯。
                if (!found)
                {
                    if (normalStateRecords.Count != 0)
                    {
                        currentState = normalStateRecords.Last();
                        normalStateRecords.RemoveAt(normalStateRecords.Count - 1);
                    }
                    else
                        break;
                }
            }

            if(currentState.Current.IsFinalState)
            {
                result.Start = startIndex;
                result.length = currentState.Position - startIndex;
                result.Records.Remove()
            }
        }
Esempio n. 2
0
 public StateInfo(StateInfo other)
 {
     Position = other.Position;
     Current = other.Current;
     MinAvaliableTransition = other.MinAvaliableTransition;
     Reason = other.Reason;
 }
Esempio n. 3
0
        private bool Match(string input, int startIndex, out RichResult result)
        {
            result = new RichResult();
            var normalStateRecords = new List <StateInfo>();
            var extStateRecords    = new List <ExtensionStateInfo>();
            var currentState       = new StateInfo
            {
                Position = 0,
                Current  = _dfa.StartState,
                MinAvaliableTransition = 0,
                Reason = StateInfo.SaveReason.Other
            };

            normalStateRecords.Add(currentState);

            while (!currentState.Current.IsFinalState)
            {
                bool found       = false;
                var  stateToSave = new StateInfo(currentState);
                for (int i = 0; i < currentState.Current.Output.Count; ++i)
                {
                    var transition = currentState.Current.Output[i];
                    switch (transition.TransitionType)
                    {
                    case Transition.Type.Chars:
                        var c     = input[currentState.Position];
                        var range = transition.Range;
                        if (c >= range.Begin && c <= range.End)
                        {
                            currentState.Current = transition.End;
                            currentState.Position++;
                        }
                        else
                        {
                            found = false;
                        }
                        break;

                    case Transition.Type.BeginString:
                        found = currentState.Position == 0;
                        break;

                    case Transition.Type.EndString:
                        found = currentState.Position == input.Length - 1;
                        break;

                    case Transition.Type.Nop:
                        found = true;
                        break;

                    case Transition.Type.Capture:
                    {
                        var captureRecord = new CaptureRecord
                        {
                            CaptureIndex = transition.Capture,
                            StartIndex   = currentState.Position,
                            MatchLength  = -1
                        };
                        result.Records.Add(captureRecord);
                        var extStateInfo = new ExtensionStateInfo
                        {
                            Position        = currentState.Position,
                            SavedTransition = transition
                        };
                        extStateRecords.Add(extStateInfo);
                        found = true;
                    }
                    break;

                    case Transition.Type.Match:
                        int index = 0;
                        foreach (var record in result.Records)
                        {
                            if (record.CaptureIndex == transition.Capture)
                            {
                                if (record.MatchLength != -1 && (transition.Index == -1 || transition.Index == index))
                                {
                                    if (input.Substring(record.StartIndex, record.MatchLength) == input.Substring(currentState.Position, record.MatchLength))
                                    {
                                        currentState.Position += record.MatchLength;
                                        found = true;
                                        break;
                                    }
                                }
                                else
                                {
                                    ++index;
                                }
                            }
                        }
                        break;

                    case Transition.Type.Positive:
                    {
                        var extStateInfo = new ExtensionStateInfo
                        {
                            Position        = currentState.Position,
                            SavedTransition = transition
                        };

                        extStateRecords.Add(extStateInfo);
                        stateToSave.Reason = StateInfo.SaveReason.Positive;
                    }
                    break;

                    case Transition.Type.End:
                        var prevState = extStateRecords.Last();
                        extStateRecords.RemoveAt(extStateRecords.Count - 1);
                        switch (prevState.SavedTransition.TransitionType)
                        {
                        case Transition.Type.Capture:
                        {
                            var capture = result.Records[prevState.CaptureListIndex];
                            capture.MatchLength = currentState.Position - prevState.Position;
                            found = true;
                        }
                        break;

                        case Transition.Type.Positive:
                        {
                            //Positive 结束后,回到初始 Positive 状态。
                            for (int j = normalStateRecords.Count - 1; j >= 0; --j)
                            {
                                var state = normalStateRecords[j];
                                if (state.Reason == StateInfo.SaveReason.Positive)
                                {
                                    currentState.Position = state.Position;
                                    stateToSave.Position  = state.Position;
                                    break;
                                }
                            }
                            found = true;
                        }
                        break;

                        default:
                            break;
                        }
                        break;

                    default:
                        break;
                    }
                    if (found)
                    {
                        //有一条边是可以过的。
                        var userData = (UserData)currentState.Current.UserData;
                        if (userData.ShouldBeSaved == true)
                        {
                            stateToSave.MinAvaliableTransition = i + 1;
                            normalStateRecords.Add(stateToSave);
                        }
                        currentState.Current = transition.End;
                        currentState.MinAvaliableTransition = 0;
                    }
                }
                //试过了所有的边,都没有找到,回溯。
                if (!found)
                {
                    if (normalStateRecords.Count != 0)
                    {
                        currentState = normalStateRecords.Last();
                        normalStateRecords.RemoveAt(normalStateRecords.Count - 1);
                    }
                    else
                    {
                        break;
                    }
                }
            }

            if (currentState.Current.IsFinalState)
            {
                result.Start  = startIndex;
                result.length = currentState.Position - startIndex;
                result.Records.Remove()
            }
        }