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() } }
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() } }