Example #1
0
func new(g *ast.Grammar, record bool) (*Mem, error) {
	simp := interp.NewSimplifier(g)
	if record {
		simp = simp.OptimizeForRecord()
	}
	g = simp.Grammar()
	refs := ast.NewRefLookup(g)
	m := &Mem{
		refs:       refs,
		simplifier: simp,

		patterns:  newPatternsSet(),
		zis:       newIntsSet(),
		stackElms: newPairSet(),
		nullables: newBitsetSet(),

		Calls:           []*CallNode{},
		Returns:         []map[int]int{},
		Escapables:      []bool{},
		StateToNullable: []int{},
		Accept:          []bool{},
	}
	start := m.patterns.add([]*ast.Pattern{refs["main"]})
	e := &exprToFunc{m: make(map[*ast.Expr]funcs.Bool)}
	for _, p := range refs {
		p.Walk(e)
		if e.err != nil {
			return nil, e.err
		}
	}
	m.funcs = e.m
	m.Start = start
	return m, nil
}
Example #2
0
func TestExplosionAndSameTree(t *testing.T) {
	var input = `(
		.A:.B:.DeepLevel:.DeeperLevel:.DeepestLevel:->contains($string,"el") &
		(
			.A:.B:.Rs:._:->eq("~a",$string) &
			(
				.A:.B:.NumI32:->contains($int,[]int{28,1,52}) &
				(
					.A:.B:.NumI64:>= 1 &
					(
						.A:.B:.NumU32:<= uint(4) &
						(
							.A:.B:.NumU64:== uint(4) &
							(
								.A:.B:.YesNo:== true &
								(
									.A:.B:.BS:== []byte{0x3, 0x2, 0x1, 0x0} &
									.A:.B:.Uuid: == []byte{0x3, 0x2, 0x1, 0x0}
								)
							)
						)
					)
				)
			)
		)
	)`
	g, err := parser.ParseGrammar(input)
	if err != nil {
		t.Fatal(err)
	}
	// This one causes a state explosion of over 14000 states.
	// Since we know field names can't repeat the simplification can be made for record (JSON and proto) like serialization formats, but not for XML.
	g = interp.NewSimplifier(g).OptimizeForRecord().Grammar()
	t.Logf("%v", g)
	a, err := Compile(g)
	if err != nil {
		t.Fatal(err)
	}
	t.Logf("number of states %d", len(a.accept))
	if len(a.accept) > 1000 {
		t.Fatal("number of states exploded")
	}
}