More progress on backreference implementation
This commit is contained in:
@@ -228,45 +228,25 @@ func (re Reg) FindAllStringSubmatch(str string) [][]string {
|
||||
return rtv
|
||||
}
|
||||
|
||||
// Second parameter is the 'new index'
|
||||
func addStateToList(str []rune, idx int, list []nfaState, state nfaState, threadGroups []Group, visited []nfaState, preferLongest bool) ([]nfaState, int) {
|
||||
func addStateToList(str []rune, idx int, list []nfaState, state nfaState, threadGroups []Group, visited []nfaState, preferLongest bool) []nfaState {
|
||||
if stateExists(list, state) || stateExists(visited, state) {
|
||||
return list, idx
|
||||
return list
|
||||
}
|
||||
visited = append(visited, state)
|
||||
|
||||
if state.isBackreference {
|
||||
if threadGroups[state.referredGroup].IsValid() {
|
||||
groupLength := threadGroups[state.referredGroup].EndIdx - threadGroups[state.referredGroup].StartIdx
|
||||
if state.threadBackref == groupLength {
|
||||
state.threadBackref = 0
|
||||
copyThread(state.next, state)
|
||||
return addStateToList(str, idx+groupLength, list, *state.next, threadGroups, visited, preferLongest)
|
||||
}
|
||||
idxInReferredGroup := threadGroups[state.referredGroup].StartIdx + state.threadBackref
|
||||
if idxInReferredGroup < len(str) && idx+state.threadBackref < len(str) && str[idxInReferredGroup] == str[idx+state.threadBackref] {
|
||||
state.threadBackref += 1
|
||||
return addStateToList(str, idx, list, state, threadGroups, visited, preferLongest)
|
||||
} else {
|
||||
return list, idx
|
||||
}
|
||||
} else {
|
||||
return list, idx
|
||||
}
|
||||
}
|
||||
if state.isKleene || state.isQuestion {
|
||||
copyThread(state.splitState, state)
|
||||
list, newIdx := addStateToList(str, idx, list, *state.splitState, threadGroups, visited, preferLongest)
|
||||
list := addStateToList(str, idx, list, *state.splitState, threadGroups, visited, preferLongest)
|
||||
copyThread(state.next, state)
|
||||
list, newIdx = addStateToList(str, newIdx, list, *state.next, threadGroups, visited, preferLongest)
|
||||
return list, newIdx
|
||||
list = addStateToList(str, idx, list, *state.next, threadGroups, visited, preferLongest)
|
||||
return list
|
||||
}
|
||||
if state.isAlternation {
|
||||
copyThread(state.next, state)
|
||||
list, newIdx := addStateToList(str, idx, list, *state.next, threadGroups, visited, preferLongest)
|
||||
list := addStateToList(str, idx, list, *state.next, threadGroups, visited, preferLongest)
|
||||
copyThread(state.splitState, state)
|
||||
list, newIdx = addStateToList(str, newIdx, list, *state.splitState, threadGroups, visited, preferLongest)
|
||||
return list, newIdx
|
||||
list = addStateToList(str, idx, list, *state.splitState, threadGroups, visited, preferLongest)
|
||||
return list
|
||||
}
|
||||
state.threadGroups = append([]Group{}, threadGroups...)
|
||||
if state.assert != noneAssert {
|
||||
@@ -285,7 +265,7 @@ func addStateToList(str []rune, idx int, list []nfaState, state nfaState, thread
|
||||
copyThread(state.next, state)
|
||||
return addStateToList(str, idx, list, *state.next, state.threadGroups, visited, preferLongest)
|
||||
}
|
||||
return append(list, state), idx
|
||||
return append(list, state)
|
||||
|
||||
}
|
||||
|
||||
@@ -315,7 +295,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, nil, preferLongest) // We can't go forward at the beginning, so I discard the second retval
|
||||
currentStates = addStateToList(str, i, currentStates, *start, start.threadGroups, nil, preferLongest)
|
||||
var match Match = nil
|
||||
for idx := i; idx <= len(str); idx++ {
|
||||
if len(currentStates) == 0 {
|
||||
@@ -335,13 +315,25 @@ func findAllSubmatchHelper(start *nfaState, str []rune, offset int, numGroups in
|
||||
if !preferLongest {
|
||||
break
|
||||
}
|
||||
} else if !currentState.isAlternation && !currentState.isKleene && !currentState.isQuestion && !currentState.groupBegin && !currentState.groupEnd && currentState.assert == noneAssert { // Normal character
|
||||
} else if !currentState.isAlternation && !currentState.isKleene && !currentState.isQuestion && !currentState.isBackreference && !currentState.groupBegin && !currentState.groupEnd && currentState.assert == noneAssert { // Normal character
|
||||
if currentState.contentContains(str, idx, preferLongest) {
|
||||
var newIdx int
|
||||
nextStates, newIdx = addStateToList(str, idx+1, nextStates, *currentState.next, currentState.threadGroups, nil, preferLongest)
|
||||
idx = newIdx - 1
|
||||
nextStates = addStateToList(str, idx+1, nextStates, *currentState.next, currentState.threadGroups, nil, preferLongest)
|
||||
}
|
||||
} else if currentState.isBackreference {
|
||||
groupLength := currentState.threadGroups[currentState.referredGroup].EndIdx - currentState.threadGroups[currentState.referredGroup].StartIdx
|
||||
if currentState.threadBackref == groupLength {
|
||||
currentState.threadBackref = 0
|
||||
copyThread(currentState.next, currentState)
|
||||
currentStates = addStateToList(str, idx, currentStates, *currentState.next, currentState.threadGroups, nil, preferLongest)
|
||||
} else {
|
||||
idxInReferredGroup := currentState.threadGroups[currentState.referredGroup].StartIdx + currentState.threadBackref
|
||||
if idxInReferredGroup < len(str) && idx < len(str) && str[idxInReferredGroup] == str[idx] {
|
||||
currentState.threadBackref += 1
|
||||
nextStates = append(nextStates, currentState)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
currentStates = append([]nfaState{}, nextStates...)
|
||||
nextStates = nil
|
||||
|
Reference in New Issue
Block a user