Ejemplo n.º 1
0
/* 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
}
Ejemplo n.º 2
0
/* 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]
		}
	}
}