|
|
|
@ -51,54 +51,54 @@ func cloneState(start *State) *State {
|
|
|
|
|
// Helper function for clone. The map is used to keep track of which states have
|
|
|
|
|
// already been copied, and which ones haven't.
|
|
|
|
|
// This function was created using output from Llama3.1:405B.
|
|
|
|
|
func cloneStateHelper(state *State, cloneMap map[*State]*State) *State {
|
|
|
|
|
func cloneStateHelper(stateToClone *State, cloneMap map[*State]*State) *State {
|
|
|
|
|
// Base case - if the clone exists in our map, return it.
|
|
|
|
|
if clone, exists := cloneMap[state]; exists {
|
|
|
|
|
if clone, exists := cloneMap[stateToClone]; exists {
|
|
|
|
|
return clone
|
|
|
|
|
}
|
|
|
|
|
if state == nil {
|
|
|
|
|
if stateToClone == nil {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
// Recursive case - if the clone doesn't exist, create it, add it to the map,
|
|
|
|
|
// and recursively call for each of the transition states.
|
|
|
|
|
clone := &State{
|
|
|
|
|
content: append([]int{}, state.content...),
|
|
|
|
|
isEmpty: state.isEmpty,
|
|
|
|
|
isLast: state.isLast,
|
|
|
|
|
output: make([]*State, len(state.output)),
|
|
|
|
|
content: append([]int{}, stateToClone.content...),
|
|
|
|
|
isEmpty: stateToClone.isEmpty,
|
|
|
|
|
isLast: stateToClone.isLast,
|
|
|
|
|
output: make([]*State, len(stateToClone.output)),
|
|
|
|
|
transitions: make(map[int][]*State),
|
|
|
|
|
isKleene: state.isKleene,
|
|
|
|
|
assert: state.assert,
|
|
|
|
|
zeroMatchFound: state.zeroMatchFound,
|
|
|
|
|
allChars: state.allChars,
|
|
|
|
|
except: append([]rune{}, state.except...),
|
|
|
|
|
lookaroundRegex: state.lookaroundRegex,
|
|
|
|
|
groupEnd: state.groupEnd,
|
|
|
|
|
groupBegin: state.groupBegin,
|
|
|
|
|
groupNum: state.groupNum,
|
|
|
|
|
isKleene: stateToClone.isKleene,
|
|
|
|
|
assert: stateToClone.assert,
|
|
|
|
|
zeroMatchFound: stateToClone.zeroMatchFound,
|
|
|
|
|
allChars: stateToClone.allChars,
|
|
|
|
|
except: append([]rune{}, stateToClone.except...),
|
|
|
|
|
lookaroundRegex: stateToClone.lookaroundRegex,
|
|
|
|
|
groupEnd: stateToClone.groupEnd,
|
|
|
|
|
groupBegin: stateToClone.groupBegin,
|
|
|
|
|
groupNum: stateToClone.groupNum,
|
|
|
|
|
}
|
|
|
|
|
cloneMap[state] = clone
|
|
|
|
|
for i, s := range state.output {
|
|
|
|
|
if s == state {
|
|
|
|
|
cloneMap[stateToClone] = clone
|
|
|
|
|
for i, s := range stateToClone.output {
|
|
|
|
|
if s == stateToClone {
|
|
|
|
|
clone.output[i] = clone
|
|
|
|
|
} else {
|
|
|
|
|
clone.output[i] = cloneStateHelper(s, cloneMap)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
for k, v := range state.transitions {
|
|
|
|
|
for k, v := range stateToClone.transitions {
|
|
|
|
|
clone.transitions[k] = make([]*State, len(v))
|
|
|
|
|
for i, s := range v {
|
|
|
|
|
if s == state {
|
|
|
|
|
if s == stateToClone {
|
|
|
|
|
clone.transitions[k][i] = clone
|
|
|
|
|
} else {
|
|
|
|
|
clone.transitions[k][i] = cloneStateHelper(s, cloneMap)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if state.lookaroundNFA == state {
|
|
|
|
|
if stateToClone.lookaroundNFA == stateToClone {
|
|
|
|
|
clone.lookaroundNFA = clone
|
|
|
|
|
}
|
|
|
|
|
clone.lookaroundNFA = cloneStateHelper(state.lookaroundNFA, cloneMap)
|
|
|
|
|
clone.lookaroundNFA = cloneStateHelper(stateToClone.lookaroundNFA, cloneMap)
|
|
|
|
|
return clone
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|