Store all states visited in a single run of 'addStateToList()' in a slice

implementPCREMatchingRules
Aadhavan Srinivasan 4 weeks ago
parent 62ca1a872a
commit f15a5cae34

@ -251,38 +251,40 @@ func (regex Reg) FindAllSubmatch(str string) []Match {
return indices return indices
} }
func addStateToList(str []rune, idx int, list []nfaState, state nfaState, threadGroups []Group) []nfaState { func addStateToList(str []rune, idx int, list []nfaState, state nfaState, threadGroups []Group, visited []nfaState) []nfaState {
if stateExists(list, state) { if stateExists(list, state) || stateExists(visited, state) {
return list return list
} }
visited = append(visited, state)
if state.isKleene || state.isQuestion { if state.isKleene || state.isQuestion {
copyThread(state.splitState, state) 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) copyThread(state.next, state)
list = addStateToList(str, idx, list, *state.next, threadGroups) list = addStateToList(str, idx, list, *state.next, threadGroups, visited)
return list return list
} }
if state.isAlternation { if state.isAlternation {
copyThread(state.next, state) 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) copyThread(state.splitState, state)
list = addStateToList(str, idx, list, *state.splitState, threadGroups) list = addStateToList(str, idx, list, *state.splitState, threadGroups, visited)
return list return list
} }
state.threadGroups = append([]Group{}, threadGroups...) state.threadGroups = append([]Group{}, threadGroups...)
if state.assert != noneAssert { if state.assert != noneAssert {
if state.checkAssertion(str, idx) { if state.checkAssertion(str, idx) {
copyThread(state.next, state) 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 { if state.groupBegin {
state.threadGroups[state.groupNum].StartIdx = idx 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 { if state.groupEnd {
state.threadGroups[state.groupNum].EndIdx = idx 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) 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 = newMatch(numGroups + 1)
start.threadGroups[0].StartIdx = i 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 match Match = nil
// var isEmptyAndNoAssertion bool // var isEmptyAndNoAssertion bool
// Main loop // Main loop
@ -366,7 +368,7 @@ func findAllSubmatchHelper(start *nfaState, str []rune, offset int, numGroups in
break break
} else if !currentState.isAlternation && !currentState.isKleene && !currentState.isQuestion && !currentState.groupBegin && !currentState.groupEnd { // Normal character or assertion } else if !currentState.isAlternation && !currentState.isKleene && !currentState.isQuestion && !currentState.groupBegin && !currentState.groupEnd { // Normal character or assertion
if currentState.contentContains(str, idx) { 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)
} }
} }

Loading…
Cancel
Save