Beispiel #1
0
func format(t *testing.T, input string, expected string) {
	g, err := parser.ParseGrammar(input)
	if err != nil {
		t.Errorf("parse error: %v given input: <%s>", err, input)
		return
	}
	g.Format()
	output := g.String()
	if expected != output {
		expectedStr := strings.Replace(strings.Replace(expected, " ", "_", -1), "\t", "<tab>", -1)
		outputStr := strings.Replace(strings.Replace(output, " ", "_", -1), "\t", "<tab>", -1)
		t.Errorf("format failure: expected \n<%s>, but got \n<%s>", expectedStr, outputStr)
	}
	input = expected
	g2, err := parser.ParseGrammar(input)
	if err != nil {
		t.Errorf("parse error2: %v given input: <%s>", err, input)
		return
	}
	g2.Format()
	output = g.String()
	if expected != output {
		expectedStr := strings.Replace(strings.Replace(expected, " ", "_", -1), "\t", "<tab>", -1)
		outputStr := strings.Replace(strings.Replace(output, " ", "_", -1), "\t", "<tab>", -1)
		t.Errorf("format failure2: expected \n<%s>, but got \n<%s>", expectedStr, outputStr)
	}
}
Beispiel #2
0
func BenchmarkCompileOrProtoName(b *testing.B) {
	st, err := parser.ParseGrammar(typewriterOrQueryStr)
	if err != nil {
		b.Fatal(err)
	}
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		if _, err := Compile(st); err != nil {
			b.Fatal(err)
		}
	}
}
Beispiel #3
0
func benchCompile(b *testing.B, str string) {
	st, err := parser.ParseGrammar(str)
	if err != nil {
		b.Fatal(err)
	}
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		if _, err := Compile(st); err != nil {
			b.Fatal(err)
		}
	}
}
Beispiel #4
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")
	}
}
Beispiel #5
0
func TestRecursionNegative(t *testing.T) {
	negatives := []string{
		`A:@main`,
		`#main = A:@main`,
		`#main = (A:* | B:@main)`,
		`#main = (A:* | @ref)
		 #ref = C:@main`,
		`#main = (A:* | @ref)
		 #ref = (B:* | D:@main | <empty>)`,
	}
	for _, n := range negatives {
		g, err := parser.ParseGrammar(n)
		if err != nil {
			t.Fatal(err)
		}
		if HasRecursion(g) {
			t.Errorf("unexpected recursion for %v", g)
		}
	}
}
Beispiel #6
0
func TestRecursionPositive(t *testing.T) {
	positives := []string{
		`@main`,
		`#main = @main`,
		`#main = (A:* | @main)`,
		`#main = (A:* | @ref)
		 #ref = @main`,
		`#main = (A:* | @ref)	#ref = (B:* | @main | <empty>)`,
		`#main = A:@ref 		#ref = @ref`,
	}
	for _, p := range positives {
		g, err := parser.ParseGrammar(p)
		if err != nil {
			t.Fatal(err)
		}
		if !HasRecursion(g) {
			t.Errorf("expected recursion for %v", g)
		}
	}
}
Beispiel #7
0
//Parse parses the relapse string into an ast (abstract syntax tree)
func Parse(relapse string) (*ast.Grammar, error) {
	return relapseparser.ParseGrammar(relapse)
}