Replaced pointer to nfaState with nfaState

implementPCREMatchingRules
Aadhavan Srinivasan 1 month ago
parent 3ce611d121
commit d4e8cb74fd

@ -151,6 +151,11 @@ func pruneIndices(indices []Match) []Match {
return toRet return toRet
} }
func copyThread(to *nfaState, from nfaState) {
to.threadSP = from.threadSP
to.threadGroups = from.threadGroups
}
// Find returns the 0-group of the leftmost match of the regex in the given string. // Find returns the 0-group of the leftmost match of the regex in the given string.
// An error value != nil indicates that no match was found. // An error value != nil indicates that no match was found.
func (regex Reg) Find(str string) (Group, error) { func (regex Reg) Find(str string) (Group, error) {
@ -271,7 +276,7 @@ func findAllSubmatchHelper(start *nfaState, str []rune, offset int, numGroups in
// foundPath := false // foundPath := false
//startIdx := offset //startIdx := offset
//endIdx := offset //endIdx := offset
currentStates := make([]*nfaState, 0) currentStates := make([]nfaState, 0)
// tempStates := make([]*nfaState, 0) // Used to store states that should be used in next loop iteration // tempStates := make([]*nfaState, 0) // Used to store states that should be used in next loop iteration
i := offset // Index in string i := offset // Index in string
//startingFrom := i // Store starting index //startingFrom := i // Store starting index
@ -302,13 +307,15 @@ func findAllSubmatchHelper(start *nfaState, str []rune, offset int, numGroups in
//} //}
start.threadSP = i start.threadSP = i
currentStates = append(currentStates, start) currentStates = append(currentStates, *start)
var foundMatch bool var foundMatch bool
var isEmptyAndNoAssertion bool
// Main loop // Main loop
for len(currentStates) > 0 { for len(currentStates) > 0 {
currentState, _ := pop(&currentStates) currentState, _ := pop(&currentStates)
idx := currentState.threadSP idx := currentState.threadSP
foundMatch = false foundMatch = false
isEmptyAndNoAssertion = false
if currentState.threadGroups == nil { if currentState.threadGroups == nil {
currentState.threadGroups = newMatch(numGroups + 1) currentState.threadGroups = newMatch(numGroups + 1)
@ -343,44 +350,39 @@ func findAllSubmatchHelper(start *nfaState, str []rune, offset int, numGroups in
// continue // continue
// } // }
// Alternation - enqueue left then right state, and continue
if currentState.isAlternation { if currentState.isAlternation {
rightState := currentState.rightState rightState := currentState.rightState
rightState.threadGroups = currentState.threadGroups copyThread(rightState, currentState)
rightState.threadSP = currentState.threadSP currentStates = append(currentStates, *currentState.rightState)
currentStates = append(currentStates, currentState.rightState)
leftState := currentState.leftState leftState := currentState.leftState
leftState.threadGroups = currentState.threadGroups copyThread(leftState, currentState)
leftState.threadSP = currentState.threadSP currentStates = append(currentStates, *currentState.leftState)
currentStates = append(currentStates, currentState.leftState)
continue continue
} }
// Empty state - enqueue next state, do _not_ increment the SP
if currentState.isEmpty && currentState.assert == noneAssert { if currentState.isEmpty && currentState.assert == noneAssert {
allMatches := make([]*nfaState, 0) isEmptyAndNoAssertion = true
for _, v := range currentState.transitions {
allMatches = append(allMatches, v...)
}
slices.Reverse(allMatches)
for _, m := range allMatches {
m.threadGroups = currentState.threadGroups
m.threadSP = idx
}
currentStates = append(currentStates, allMatches...)
} }
if currentState.contentContains(str, idx) { if currentState.contentContains(str, idx) {
foundMatch = true foundMatch = true
allMatches := make([]*nfaState, 0) }
if isEmptyAndNoAssertion || foundMatch {
allMatches := make([]nfaState, 0)
for _, v := range currentState.transitions { for _, v := range currentState.transitions {
allMatches = append(allMatches, v...) dereferenced := funcMap(v, func(s *nfaState) nfaState {
return *s
})
allMatches = append(allMatches, dereferenced...)
} }
slices.Reverse(allMatches) slices.Reverse(allMatches)
for _, m := range allMatches { for i := range allMatches {
m.threadGroups = currentState.threadGroups copyThread(&allMatches[i], currentState)
if currentState.assert == noneAssert { if foundMatch && currentState.assert == noneAssert {
m.threadSP = idx + 1 allMatches[i].threadSP += 1
} else {
m.threadSP = idx
} }
} }
currentStates = append(currentStates, allMatches...) currentStates = append(currentStates, allMatches...)
@ -388,8 +390,15 @@ func findAllSubmatchHelper(start *nfaState, str []rune, offset int, numGroups in
if currentState.isLast { // Last state reached if currentState.isLast { // Last state reached
if foundMatch { if foundMatch {
if currentState.assert != noneAssert {
currentState.threadGroups[0].EndIdx = idx
} else {
currentState.threadGroups[0].EndIdx = idx + 1 currentState.threadGroups[0].EndIdx = idx + 1
return true, currentState.threadGroups, idx + 1 }
if idx == currentState.threadGroups[0].StartIdx {
idx += 1
}
return true, currentState.threadGroups, idx
} else if currentState.isEmpty && currentState.assert == noneAssert { } else if currentState.isEmpty && currentState.assert == noneAssert {
currentState.threadGroups[0].EndIdx = idx currentState.threadGroups[0].EndIdx = idx
if idx == currentState.threadGroups[0].StartIdx { if idx == currentState.threadGroups[0].StartIdx {

Loading…
Cancel
Save