예제 #1
0
파일: wrapper.go 프로젝트: emersion/tomato
func New(endsNbr int) (*tomato.Automaton, func(*tomato.Automaton)) {
	start := tomato.NewState()

	ends := make([]*tomato.State, endsNbr)
	for i := 0; i < endsNbr; i++ {
		ends[i] = tomato.NewState()
	}

	return tomato.NewAutomaton(start, ends), func(automaton *tomato.Automaton) {
		start.Reset()
		start.Add(transition.NewAutomaton(automaton, ends))
	}
}
예제 #2
0
func jsonValue(number, str, array, object *tomato.Automaton) *tomato.Automaton {
	q0 := tomato.NewState()
	q1 := tomato.NewState()

	q0.Add(transition.NewAutomaton(str, []*tomato.State{q1}))
	q0.Add(transition.NewAutomaton(number, []*tomato.State{q1}))
	q0.Add(transition.NewAutomaton(object, []*tomato.State{q1}))
	q0.Add(transition.NewAutomaton(array, []*tomato.State{q1}))
	q0.Add(transition.NewString("true", q1))
	q0.Add(transition.NewString("false", q1))
	q0.Add(transition.NewString("null", q1))

	return tomato.NewAutomaton(q0, []*tomato.State{q1})
}
예제 #3
0
func jsonObject(str, value *tomato.Automaton) *tomato.Automaton {
	q0 := tomato.NewState()
	q1 := tomato.NewState()
	q2 := tomato.NewState()
	q3 := tomato.NewState()
	q4 := tomato.NewState()
	q5 := tomato.NewState()
	q6 := tomato.NewState()
	q7 := tomato.NewState()

	q0.Add(transition.NewRune('{', q1))

	q1.Add(transition.NewEpsilon(q2))
	q1.Add(transition.NewEpsilon(q6))

	q2.Add(transition.NewAutomaton(str, []*tomato.State{q3}))

	q3.Add(transition.NewRune(':', q4))

	q4.Add(transition.NewAutomaton(value, []*tomato.State{q5}))

	q5.Add(transition.NewRune(',', q2))
	q5.Add(transition.NewEpsilon(q6))

	q6.Add(transition.NewRune('}', q7))

	return tomato.NewAutomaton(q0, []*tomato.State{q7})
}
예제 #4
0
func jsonString() *tomato.Automaton {
	q0 := tomato.NewState()
	q1 := tomato.NewState()
	q2 := tomato.NewState()
	q2_1 := tomato.NewState()
	q2_1_1 := tomato.NewState()
	q3 := tomato.NewState()
	q4 := tomato.NewState()

	q0.Add(transition.NewRune('"', q1))

	q1.Add(transition.NewEpsilon(q2))
	q1.Add(transition.NewEpsilon(q3))

	q2.Add(transition.NewRegexp("[^\\\"]+", q3))
	q2.Add(transition.NewRune('\\', q2_1))

	q2_1.Add(transition.NewRegexp("[\"\\/bfnrt]", q3))
	q2_1.Add(transition.NewRune('u', q2_1_1))

	q2_1_1.Add(transition.NewRegexp("[0-9a-f]{4}", q3))

	q3.Add(transition.NewEpsilon(q2))
	q3.Add(transition.NewRune('"', q4))

	return tomato.NewAutomaton(q0, []*tomato.State{q4})
}
예제 #5
0
// A simple automaton that recognizes words containing "ab".
func TestContains(t *testing.T) {
	q0 := tomato.NewState()
	q1 := tomato.NewState()
	q2 := tomato.NewState()

	q0.Add(transition.NewRune('a', q1))
	q0.Add(transition.NewRune('b', q0))
	q0.Add(transition.NewRune('c', q0))

	q1.Add(transition.NewRune('a', q1))
	q1.Add(transition.NewRune('b', q2))
	q1.Add(transition.NewRune('c', q0))

	q2.Add(transition.NewRune('a', q2))
	q2.Add(transition.NewRune('b', q2))
	q2.Add(transition.NewRune('c', q2))

	a := tomato.NewAutomaton(q0, []*tomato.State{q2})

	items := []testCase{
		{"ab", true},
		{"abc", true},
		{"cab", true},
		{"cabc", true},
		{"aaaab", true},
		{"aba", true},
		{"abab", true},
		{"acab", true},
		{"a", false},
		{"b", false},
		{"aa", false},
		{"ba", false},
		{"bbbaaa", false},
		{"aca", false},
	}

	testAll(t, a, items)
}
예제 #6
0
파일: det.go 프로젝트: emersion/tomato
// Transform any automaton to a synchronized and determinized automaton.
func Determinize(a *tomato.Automaton) *tomato.Automaton {
	closures := []Closure{}
	states := []*tomato.State{}
	ends := []*tomato.State{}

	var collect func(state *tomato.State) *tomato.State
	collect = func(state *tomato.State) *tomato.State {
		closure := EpsilonClosure(state)

		// Make sure this closure hasn't been already processed
		for i, c := range closures {
			if closure.equals(c) {
				return states[i]
			}
		}

		// Create a new state for this closure
		state = tomato.NewState()

		// Collect this closure's transitons
		trs := closureTransitions(closure)

		// Add closure & new state to list
		closures = append(closures, closure)
		states = append(states, state)

		// Does this new state is an ending one?
		if closureIsEnd(closure, a.Ends()) {
			ends = append(ends, state)
		}

		// Add transitions to new state
		for _, tr := range trs {
			targets := tr.Targets()
			newTargets := make([]*tomato.State, len(targets))
			for i, target := range targets {
				newTargets[i] = collect(target)
			}
			state.Add(tr.Duplicate(newTargets...))
		}

		return state
	}

	root := collect(a.Root())

	return tomato.NewAutomaton(root, ends)
}
예제 #7
0
func jsonArray(value *tomato.Automaton) *tomato.Automaton {
	q0 := tomato.NewState()
	q1 := tomato.NewState()
	q2 := tomato.NewState()
	q3 := tomato.NewState()
	q4 := tomato.NewState()
	q5 := tomato.NewState()

	q0.Add(transition.NewRune('[', q1))

	q1.Add(transition.NewEpsilon(q2))
	q1.Add(transition.NewEpsilon(q4))

	q2.Add(transition.NewAutomaton(value, []*tomato.State{q3}))

	q3.Add(transition.NewRune(',', q2))
	q3.Add(transition.NewEpsilon(q4))

	q4.Add(transition.NewRune(']', q5))

	return tomato.NewAutomaton(q0, []*tomato.State{q5})
}
예제 #8
0
func jsonNumber() *tomato.Automaton {
	q0 := tomato.NewState()
	q1 := tomato.NewState()
	q1_1 := tomato.NewState()
	q2 := tomato.NewState()
	q3 := tomato.NewState()
	q4 := tomato.NewState()
	q5 := tomato.NewState()
	q5_1 := tomato.NewState()
	q5_2 := tomato.NewState()
	q5_3 := tomato.NewState()
	q6 := tomato.NewState()

	q0.Add(transition.NewRune('-', q1))
	q0.Add(transition.NewEpsilon(q1))

	q1.Add(transition.NewRune('0', q2))
	q1.Add(transition.NewRegexp("[1-9]", q1_1))

	q1_1.Add(transition.NewRegexp("[0-9]", q1_1))
	q1_1.Add(transition.NewEpsilon(q2))

	q2.Add(transition.NewEpsilon(q5))
	q2.Add(transition.NewRune('.', q3))

	q3.Add(transition.NewRegexp("[0-9]", q4))

	q4.Add(transition.NewRegexp("[0-9]", q4))
	q4.Add(transition.NewEpsilon(q5))

	q5.Add(transition.NewRegexp("[eE]", q5_1))
	q5.Add(transition.NewEpsilon(q6))

	q5_1.Add(transition.NewRegexp("[+-]?", q5_2))

	q5_2.Add(transition.NewRegexp("[0-9]", q5_3))

	q5_3.Add(transition.NewRegexp("[0-9]", q5_3))
	q5_3.Add(transition.NewEpsilon(q6))

	return tomato.NewAutomaton(q0, []*tomato.State{q6})
}