Started implementing Thompson's algorithm for matching, because the old one was completely backtracking (so it would enter infinite loops on something like '(a*)*' )

The git diff claims that a ton of code was changed, but most of it was just indentation changes.
implementPCREMatchingRules
Aadhavan Srinivasan 1 month ago
parent d4e8cb74fd
commit 7c62ba6bfd

@ -277,6 +277,7 @@ func findAllSubmatchHelper(start *nfaState, str []rune, offset int, numGroups in
//startIdx := offset //startIdx := offset
//endIdx := offset //endIdx := offset
currentStates := make([]nfaState, 0) currentStates := make([]nfaState, 0)
nextStates := 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
@ -311,9 +312,9 @@ func findAllSubmatchHelper(start *nfaState, str []rune, offset int, numGroups in
var foundMatch bool var foundMatch bool
var isEmptyAndNoAssertion bool var isEmptyAndNoAssertion bool
// Main loop // Main loop
for len(currentStates) > 0 { for idx := i; idx <= len(str); idx++ {
currentState, _ := pop(&currentStates) for currentStateIdx := 0; currentStateIdx < len(currentStates); currentStateIdx++ {
idx := currentState.threadSP currentState := currentStates[currentStateIdx]
foundMatch = false foundMatch = false
isEmptyAndNoAssertion = false isEmptyAndNoAssertion = false
@ -352,12 +353,12 @@ func findAllSubmatchHelper(start *nfaState, str []rune, offset int, numGroups in
// Alternation - enqueue left then right state, and continue // Alternation - enqueue left then right state, and continue
if currentState.isAlternation { if currentState.isAlternation {
rightState := currentState.rightState
copyThread(rightState, currentState)
currentStates = append(currentStates, *currentState.rightState)
leftState := currentState.leftState leftState := currentState.leftState
copyThread(leftState, currentState) copyThread(leftState, currentState)
currentStates = append(currentStates, *currentState.leftState) currentStates = append(currentStates, *currentState.leftState)
rightState := currentState.rightState
copyThread(rightState, currentState)
currentStates = append(currentStates, *currentState.rightState)
continue continue
} }
@ -385,7 +386,7 @@ func findAllSubmatchHelper(start *nfaState, str []rune, offset int, numGroups in
allMatches[i].threadSP += 1 allMatches[i].threadSP += 1
} }
} }
currentStates = append(currentStates, allMatches...) nextStates = append(nextStates, allMatches...)
} }
if currentState.isLast { // Last state reached if currentState.isLast { // Last state reached
@ -409,6 +410,9 @@ func findAllSubmatchHelper(start *nfaState, str []rune, offset int, numGroups in
} }
} }
copy(currentStates, nextStates)
nextStates = nil
}
return false, []Group{}, i + 1 return false, []Group{}, i + 1
// zeroStates := make([]*nfaState, 0) // zeroStates := make([]*nfaState, 0)
// // Keep taking zero-states, until there are no more left to take // // Keep taking zero-states, until there are no more left to take

Loading…
Cancel
Save