Store all states visited in a single run of 'addStateToList()' in a slice
This commit is contained in:
@@ -251,38 +251,40 @@ func (regex Reg) FindAllSubmatch(str string) []Match {
|
||||
return indices
|
||||
}
|
||||
|
||||
func addStateToList(str []rune, idx int, list []nfaState, state nfaState, threadGroups []Group) []nfaState {
|
||||
if stateExists(list, state) {
|
||||
func addStateToList(str []rune, idx int, list []nfaState, state nfaState, threadGroups []Group, visited []nfaState) []nfaState {
|
||||
if stateExists(list, state) || stateExists(visited, state) {
|
||||
return list
|
||||
}
|
||||
visited = append(visited, state)
|
||||
|
||||
if state.isKleene || state.isQuestion {
|
||||
copyThread(state.splitState, state)
|
||||
list = addStateToList(str, idx, list, *state.splitState, threadGroups)
|
||||
list = addStateToList(str, idx, list, *state.splitState, threadGroups, visited)
|
||||
copyThread(state.next, state)
|
||||
list = addStateToList(str, idx, list, *state.next, threadGroups)
|
||||
list = addStateToList(str, idx, list, *state.next, threadGroups, visited)
|
||||
return list
|
||||
}
|
||||
if state.isAlternation {
|
||||
copyThread(state.next, state)
|
||||
list = addStateToList(str, idx, list, *state.next, threadGroups)
|
||||
list = addStateToList(str, idx, list, *state.next, threadGroups, visited)
|
||||
copyThread(state.splitState, state)
|
||||
list = addStateToList(str, idx, list, *state.splitState, threadGroups)
|
||||
list = addStateToList(str, idx, list, *state.splitState, threadGroups, visited)
|
||||
return list
|
||||
}
|
||||
state.threadGroups = append([]Group{}, threadGroups...)
|
||||
if state.assert != noneAssert {
|
||||
if state.checkAssertion(str, idx) {
|
||||
copyThread(state.next, state)
|
||||
return append(list, addStateToList(str, idx, list, *state.next, state.threadGroups)...)
|
||||
return addStateToList(str, idx, list, *state.next, state.threadGroups, visited)
|
||||
}
|
||||
}
|
||||
if state.groupBegin {
|
||||
state.threadGroups[state.groupNum].StartIdx = idx
|
||||
return append(list, addStateToList(str, idx, list, *state.next, state.threadGroups)...)
|
||||
return addStateToList(str, idx, list, *state.next, state.threadGroups, visited)
|
||||
}
|
||||
if state.groupEnd {
|
||||
state.threadGroups[state.groupNum].EndIdx = idx
|
||||
return append(list, addStateToList(str, idx, list, *state.next, state.threadGroups)...)
|
||||
return addStateToList(str, idx, list, *state.next, state.threadGroups, visited)
|
||||
}
|
||||
return append(list, state)
|
||||
|
||||
@@ -344,7 +346,7 @@ func findAllSubmatchHelper(start *nfaState, str []rune, offset int, numGroups in
|
||||
|
||||
start.threadGroups = newMatch(numGroups + 1)
|
||||
start.threadGroups[0].StartIdx = i
|
||||
currentStates = addStateToList(str, i, currentStates, *start, start.threadGroups)
|
||||
currentStates = addStateToList(str, i, currentStates, *start, start.threadGroups, nil)
|
||||
var match Match = nil
|
||||
// var isEmptyAndNoAssertion bool
|
||||
// Main loop
|
||||
@@ -366,7 +368,7 @@ func findAllSubmatchHelper(start *nfaState, str []rune, offset int, numGroups in
|
||||
break
|
||||
} else if !currentState.isAlternation && !currentState.isKleene && !currentState.isQuestion && !currentState.groupBegin && !currentState.groupEnd { // Normal character or assertion
|
||||
if currentState.contentContains(str, idx) {
|
||||
nextStates = addStateToList(str, idx+1, nextStates, *currentState.next, currentState.threadGroups)
|
||||
nextStates = addStateToList(str, idx+1, nextStates, *currentState.next, currentState.threadGroups, nil)
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user