/* Compiles all added states and transitions into a new Automaton and returns it. */ func (b *AutomatonBuilder) finish() *Automaton { // fmt.Printf("LA.Builder.finish: count=%v\n", len(b.transitions)/4) // fmt.Println("finish pending") util.NewInPlaceMergeSorter(srcMinMaxDestSorter(b.transitions)).Sort(0, len(b.transitions)/4) for upto := 0; upto < len(b.transitions); upto += 4 { b.a.addTransitionRange( b.transitions[upto], b.transitions[upto+1], b.transitions[upto+2], b.transitions[upto+3], ) } b.a.finishState() return b.a }
/* Freezes the last state, sorting and reducing the transitions. */ func (a *Automaton) finishCurrentState() { numTransitions := a.states[2*a.curState+1] assert(numTransitions > 0) offset := a.states[2*a.curState] start := offset / 3 util.NewInPlaceMergeSorter(destMinMaxSorter(a.transitions)).Sort(start, start+numTransitions) // reduce any "adjacent" transitions: upto, min, max, dest := 0, -1, -1, -1 for i := 0; i < numTransitions; i++ { tDest := a.transitions[offset+3*i] tMin := a.transitions[offset+3*i+1] tMax := a.transitions[offset+3*i+2] if dest == tDest { if tMin <= max+1 { if tMax > max { max = tMax } } else { if dest != -1 { a.transitions[offset+3*upto] = dest a.transitions[offset+3*upto+1] = min a.transitions[offset+3*upto+2] = max upto++ } min, max = tMin, tMax } } else { if dest != -1 { a.transitions[offset+3*upto] = dest a.transitions[offset+3*upto+1] = min a.transitions[offset+3*upto+2] = max upto++ } dest, min, max = tDest, tMin, tMax } } if dest != -1 { // last transition a.transitions[offset+3*upto] = dest a.transitions[offset+3*upto+1] = min a.transitions[offset+3*upto+2] = max upto++ } a.transitions = a.transitions[:len(a.transitions)-(numTransitions-upto)*3] a.states[2*a.curState+1] = upto // sort transitions by min/max/dest: util.NewInPlaceMergeSorter(minMaxDestSorter(a.transitions)).Sort(start, start+upto) if a.deterministic && upto > 1 { lastMax := a.transitions[offset+2] for i := 1; i < upto; i++ { min = a.transitions[offset+3*i+1] if min <= lastMax { a.deterministic = false break } lastMax = a.transitions[offset+3*i+2] } } }