diff --git a/nfa.go b/nfa.go index 5566579..ff6fdc6 100644 --- a/nfa.go +++ b/nfa.go @@ -32,6 +32,7 @@ type State struct { allChars bool // Whether or not the state represents all characters (eg. a 'dot' metacharacter). A 'dot' node doesn't store any contents directly, as it would take up too much space except []rune // Only valid if allChars is true - match all characters _except_ the ones in this block. Useful for inverting character classes. lookaroundRegex string // Only for lookaround states - Contents of the regex that the lookaround state holds + lookaroundNFA *State // Holds the NFA of the lookaroundRegex - if it exists } // Clones the NFA starting from the given state. @@ -47,6 +48,9 @@ func cloneStateHelper(state *State, cloneMap map[*State]*State) *State { if clone, exists := cloneMap[state]; exists { return clone } + if state == 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{ @@ -80,6 +84,10 @@ func cloneStateHelper(state *State, cloneMap map[*State]*State) *State { } } } + if state.lookaroundNFA == state { + clone.lookaroundNFA = clone + } + clone.lookaroundNFA = cloneStateHelper(state.lookaroundNFA, cloneMap) return clone } @@ -104,9 +112,7 @@ func (s State) checkAssertion(str []rune, idx int) bool { // 1. Compile the regex stored in the state's contents. // 2. Run it on the test string. // 3. Based on the kind of lookaround (and the indices we get), determine what action to take. - regex := s.lookaroundRegex - re_postfix := shuntingYard(regex) - startState := thompson(re_postfix) + startState := s.lookaroundNFA matchIndices := findAllMatches(startState, str) numMatchesFound := 0