diff --git a/regex/matching.go b/regex/matching.go index 95f7a69..06fd16b 100644 --- a/regex/matching.go +++ b/regex/matching.go @@ -152,7 +152,6 @@ func pruneIndices(indices []Match) []Match { } func copyThread(to *nfaState, from nfaState) { - to.threadSP = from.threadSP to.threadGroups = append([]Group{}, from.threadGroups...) } @@ -253,6 +252,35 @@ func (regex Reg) FindAllSubmatch(str string) []Match { return indices } +func addStateToList(idx int, list []nfaState, state nfaState) []nfaState { + if stateExists(list, state) { + return list + } + if state.isAlternation { + copyThread(state.next, state) + list = append(list, addStateToList(idx, list, *state.next)...) + copyThread(state.splitState, state) + list = append(list, addStateToList(idx, list, *state.splitState)...) + return list + } + if state.isKleene { + copyThread(state.splitState, state) + list = append(list, addStateToList(idx, list, *state.splitState)...) + copyThread(state.next, state) + list = append(list, addStateToList(idx, list, *state.next)...) + return list + } + if state.groupBegin { + state.threadGroups[state.groupNum].StartIdx = idx + } + if state.groupEnd { + state.threadGroups[state.groupNum].StartIdx = idx + } + copyThread(state.next, state) + return append(list, *state.next) + +} + // Helper for FindAllMatches. Returns whether it found a match, the // first Match it finds, and how far it got into the string ie. where // the next search should start from. @@ -307,7 +335,6 @@ func findAllSubmatchHelper(start *nfaState, str []rune, offset int, numGroups in // tempIndices[start.groupNum].startIdx = i //} - start.threadSP = i currentStates = append(currentStates, *start) var foundMatch bool var isEmptyAndNoAssertion bool @@ -404,23 +431,28 @@ func findAllSubmatchHelper(start *nfaState, str []rune, offset int, numGroups in } if isEmptyAndNoAssertion || foundMatch { - allMatches := make([]nfaState, 0) - allMatches = append(allMatches, *(currentState.next)) - slices.Reverse(allMatches) - for i := range allMatches { - copyThread(&allMatches[i], currentState) - if foundMatch && currentState.assert == noneAssert { - allMatches[i].threadSP += 1 - } - } + nextMatch := *(currentState.next) + copyThread(&nextMatch, currentState) if currentState.groupBegin { - currentStates = slices.Insert(currentStates, currentStateIdx+1, allMatches...) + // if !stateExists(currentStates, nextMatch) { + currentStates = slices.Insert(currentStates, currentStateIdx+1, nextMatch) + //} } else if currentState.groupEnd { - currentStates = append(currentStates, allMatches...) + if !stateExists(currentStates, nextMatch) { + currentStates = slices.Insert(currentStates, currentStateIdx+1, nextMatch) // append(currentStates, nextMatch) + } } else if currentState.assert != noneAssert { - currentStates = append(currentStates, allMatches...) + if !stateExists(currentStates, nextMatch) { + currentStates = append(currentStates, nextMatch) + } + } else if currentState.isEmpty && !currentState.groupBegin && !currentState.groupEnd { + if !stateExists(currentStates, nextMatch) { + currentStates = append(currentStates, nextMatch) + } } else { - nextStates = append(nextStates, allMatches...) + if !stateExists(nextStates, nextMatch) { + nextStates = append(nextStates, nextMatch) + } } }