@ -228,45 +228,25 @@ func (re Reg) FindAllStringSubmatch(str string) [][]string {
return rtv
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 {
func addStateToList ( str [ ] rune , idx int , list [ ] nfaState , state nfaState , threadGroups [ ] Group , visited [ ] nfaState , preferLongest bool ) ( [ ] nfaState , int ) {
if stateExists ( list , state ) || stateExists ( visited , state ) {
if stateExists ( list , state ) || stateExists ( visited , state ) {
return list , idx
return list
}
}
visited = append ( visited , state )
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 {
if state . isKleene || state . isQuestion {
copyThread ( state . splitState , state )
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 )
copyThread ( state . next , state )
list , newIdx = addStateToList ( str , newI dx, list , * state . next , threadGroups , visited , preferLongest )
list = addStateToList ( str , idx , list , * state . next , threadGroups , visited , preferLongest )
return list , newIdx
return list
}
}
if state . isAlternation {
if state . isAlternation {
copyThread ( state . next , state )
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 )
copyThread ( state . splitState , state )
list , newIdx = addStateToList ( str , newI dx, list , * state . splitState , threadGroups , visited , preferLongest )
list = addStateToList ( str , idx , list , * state . splitState , threadGroups , visited , preferLongest )
return list , newIdx
return list
}
}
state . threadGroups = append ( [ ] Group { } , threadGroups ... )
state . threadGroups = append ( [ ] Group { } , threadGroups ... )
if state . assert != noneAssert {
if state . assert != noneAssert {
@ -285,7 +265,7 @@ func addStateToList(str []rune, idx int, list []nfaState, state nfaState, thread
copyThread ( state . next , state )
copyThread ( state . next , state )
return addStateToList ( str , idx , list , * state . next , state . threadGroups , visited , preferLongest )
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 = newMatch ( numGroups + 1 )
start . threadGroups [ 0 ] . StartIdx = i
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
var match Match = nil
for idx := i ; idx <= len ( str ) ; idx ++ {
for idx := i ; idx <= len ( str ) ; idx ++ {
if len ( currentStates ) == 0 {
if len ( currentStates ) == 0 {
@ -335,14 +315,26 @@ func findAllSubmatchHelper(start *nfaState, str []rune, offset int, numGroups in
if ! preferLongest {
if ! preferLongest {
break
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 ) {
if currentState . contentContains ( str , idx , preferLongest ) {
var newIdx int
nextStates = addStateToList ( str , idx + 1 , nextStates , * currentState . next , currentState . threadGroups , nil , preferLongest )
nextStates , newIdx = addStateToList ( str , idx + 1 , nextStates , * currentState . next , currentState . threadGroups , nil , preferLongest )
}
idx = newIdx - 1
} 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 ... )
currentStates = append ( [ ] nfaState { } , nextStates ... )
nextStates = nil
nextStates = nil
}
}