|
|
@ -104,6 +104,26 @@ func cloneStateHelper(stateToClone *nfaState, cloneMap map[*nfaState]*nfaState)
|
|
|
|
return clone
|
|
|
|
return clone
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Reset any thread-related fields of the NFA starting from the given state.
|
|
|
|
|
|
|
|
func resetThreads(start *nfaState) {
|
|
|
|
|
|
|
|
visitedMap := make(map[*nfaState]bool) // The value type doesn't matter here
|
|
|
|
|
|
|
|
resetThreadsHelper(start, visitedMap)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func resetThreadsHelper(state *nfaState, visitedMap map[*nfaState]bool) {
|
|
|
|
|
|
|
|
if _, ok := visitedMap[state]; ok {
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// Assuming it hasn't been visited
|
|
|
|
|
|
|
|
state.threadGroups = nil
|
|
|
|
|
|
|
|
visitedMap[state] = true
|
|
|
|
|
|
|
|
for _, v := range state.transitions {
|
|
|
|
|
|
|
|
for _, nextState := range v {
|
|
|
|
|
|
|
|
resetThreadsHelper(nextState, visitedMap)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Checks if the given state's assertion is true. Returns true if the given
|
|
|
|
// Checks if the given state's assertion is true. Returns true if the given
|
|
|
|
// state doesn't have an assertion.
|
|
|
|
// state doesn't have an assertion.
|
|
|
|
func (s nfaState) checkAssertion(str []rune, idx int) bool {
|
|
|
|
func (s nfaState) checkAssertion(str []rune, idx int) bool {
|
|
|
@ -274,7 +294,7 @@ func concatenate(s1 *nfaState, s2 *nfaState) *nfaState {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for i := range s1.output {
|
|
|
|
for i := range s1.output {
|
|
|
|
for _, c := range s2.content { // Create transitions for every element in s1's content to s2'
|
|
|
|
for _, c := range s2.content { // Create transitions for every element in s1's content to s2'
|
|
|
|
s1.output[i].transitions[c], _ = unique_append(s1.output[i].transitions[c], s2)
|
|
|
|
s1.output[i].transitions[c], _ = uniqueAppend(s1.output[i].transitions[c], s2)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
s1.output = s2.output
|
|
|
|
s1.output = s2.output
|
|
|
@ -294,11 +314,11 @@ func kleene(s1 nfaState) (*nfaState, error) {
|
|
|
|
toReturn.output = append(toReturn.output, toReturn)
|
|
|
|
toReturn.output = append(toReturn.output, toReturn)
|
|
|
|
for i := range s1.output {
|
|
|
|
for i := range s1.output {
|
|
|
|
for _, c := range toReturn.content {
|
|
|
|
for _, c := range toReturn.content {
|
|
|
|
s1.output[i].transitions[c], _ = unique_append(s1.output[i].transitions[c], toReturn)
|
|
|
|
s1.output[i].transitions[c], _ = uniqueAppend(s1.output[i].transitions[c], toReturn)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for _, c := range s1.content {
|
|
|
|
for _, c := range s1.content {
|
|
|
|
toReturn.transitions[c], _ = unique_append(toReturn.transitions[c], &s1)
|
|
|
|
toReturn.transitions[c], _ = uniqueAppend(toReturn.transitions[c], &s1)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return toReturn, nil
|
|
|
|
return toReturn, nil
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -314,10 +334,10 @@ func alternate(s1 *nfaState, s2 *nfaState) *nfaState {
|
|
|
|
// This would lead to multiple instances of the same set of match indices, since both
|
|
|
|
// This would lead to multiple instances of the same set of match indices, since both
|
|
|
|
// 's1' states would be considered to match.
|
|
|
|
// 's1' states would be considered to match.
|
|
|
|
for _, c := range s1.content {
|
|
|
|
for _, c := range s1.content {
|
|
|
|
toReturn.transitions[c], _ = unique_append(toReturn.transitions[c], s1)
|
|
|
|
toReturn.transitions[c], _ = uniqueAppend(toReturn.transitions[c], s1)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for _, c := range s2.content {
|
|
|
|
for _, c := range s2.content {
|
|
|
|
toReturn.transitions[c], _ = unique_append(toReturn.transitions[c], s2)
|
|
|
|
toReturn.transitions[c], _ = uniqueAppend(toReturn.transitions[c], s2)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
toReturn.content = newContents(epsilon)
|
|
|
|
toReturn.content = newContents(epsilon)
|
|
|
|
toReturn.isEmpty = true
|
|
|
|
toReturn.isEmpty = true
|
|
|
|