//NameToFunc compiles a parsed name expression into a function. func NameToFunc(n *ast.NameExpr) funcs.Bool { typ := n.GetValue() switch v := typ.(type) { case *ast.Name: if v.DoubleValue != nil { return funcs.DoubleEq(funcs.DoubleVar(), funcs.DoubleConst(v.GetDoubleValue())) } else if v.IntValue != nil { return funcs.IntEq(funcs.IntVar(), funcs.IntConst(v.GetIntValue())) } else if v.UintValue != nil { return funcs.UintEq(funcs.UintVar(), funcs.UintConst(v.GetUintValue())) } else if v.BoolValue != nil { return funcs.BoolEq(funcs.BoolVar(), funcs.BoolConst(v.GetBoolValue())) } else if v.StringValue != nil { return funcs.StringEq(funcs.StringVar(), funcs.StringConst(v.GetStringValue())) } else if v.BytesValue != nil { return funcs.BytesEq(funcs.BytesVar(), funcs.BytesConst(v.GetBytesValue())) } panic(fmt.Sprintf("unknown name expr name %#v", v)) case *ast.AnyName: return funcs.BoolConst(true) case *ast.AnyNameExcept: return funcs.Not(NameToFunc(v.GetExcept())) case *ast.NameChoice: return funcs.Or(NameToFunc(v.GetLeft()), NameToFunc(v.GetRight())) } panic(fmt.Sprintf("unknown name expr typ %T", typ)) }
func TestSimplifyRecordLeaf2(t *testing.T) { input := ast.NewAnd( ast.NewContains(ast.NewTreeNode(ast.NewStringName("A"), ast.NewContains(ast.NewTreeNode(ast.NewStringName("B"), combinator.Value(funcs.Contains(funcs.StringVar(), funcs.StringConst("a"))))))), ast.NewContains(ast.NewTreeNode(ast.NewStringName("A"), ast.NewContains(ast.NewTreeNode(ast.NewStringName("B"), combinator.Value(funcs.Contains(funcs.StringVar(), funcs.StringConst("b"))))))), ) t.Logf("input: %v", input) expected := ast.NewContains(ast.NewTreeNode(ast.NewStringName("A"), ast.NewContains(ast.NewTreeNode(ast.NewStringName("B"), combinator.Value(funcs.And( funcs.Contains(funcs.StringVar(), funcs.StringConst("a")), funcs.Contains(funcs.StringVar(), funcs.StringConst("b")), )))))) output := NewSimplifier(input.Grammar()).OptimizeForRecord().Simplify(input) expected.Format() output.Format() t.Logf("%v", output) if !expected.Equal(output) { t.Fatalf("expected %v, but got %v", expected, output) } }
func TestSimplifyFalseLeaf(t *testing.T) { input := combinator.Value(funcs.And(funcs.StringEq(funcs.StringVar(), funcs.StringConst("a")), funcs.StringEq(funcs.StringVar(), funcs.StringConst("b")))) expected := ast.NewNot(ast.NewZAny()) output := NewSimplifier(input.Grammar()).Simplify(input) t.Logf("%v", output) if !expected.Equal(output) { t.Fatalf("expected %v, but got %v", expected, output) } }
func newList(nameOrPattern *NameOrPattern) *ast.Pattern { regexStr, nullable, err := listToRegex(nameOrPattern) if err != nil { return ast.NewNot(ast.NewZAny()) } val := combinator.Value(&list{nil, funcs.StringVar(), funcs.StringConst("^" + regexStr + "$")}) if !nullable { return val } return ast.NewOr(val, ast.NewEmpty()) }
func composeVariable(v *ast.Variable) funcs.Variable { switch v.Type { case types.SINGLE_DOUBLE: return funcs.DoubleVar() case types.SINGLE_INT: return funcs.IntVar() case types.SINGLE_UINT: return funcs.UintVar() case types.SINGLE_BOOL: return funcs.BoolVar() case types.SINGLE_STRING: return funcs.StringVar() case types.SINGLE_BYTES: return funcs.BytesVar() } panic("unreachable") }
func composeString(expr *ast.Expr) (funcs.String, error) { uniq, err := prep(expr, types.SINGLE_STRING) if err != nil { return nil, err } if expr.Terminal != nil { if expr.GetTerminal().Variable != nil { return funcs.StringVar(), nil } else { return funcs.StringConst(expr.GetTerminal().GetStringValue()), nil } } values, err := newValues(expr.GetFunction().GetParams()) if err != nil { return nil, err } return funcs.NewStringFunc(uniq, values...) }
func newTokenValue(t string) *ast.Pattern { return combinator.Value(&token{funcs.StringVar(), funcs.StringConst(t), ""}) }
func newTextValue(value string) *ast.Pattern { return combinator.Value(&text{funcs.StringVar(), funcs.StringConst(value), ""}) }
func newAnyValue() *ast.Pattern { return combinator.Value(&anytext{funcs.StringVar()}) }
func newEmptyValue() *ast.Pattern { return combinator.Value(&whitespace{funcs.StringVar()}) }
func TestSimplify1(t *testing.T) { c := ast.NewConcat(ast.NewNot(ast.NewZAny()), ast.NewZAny()) s := NewSimplifier(c.Grammar()).Simplify(c) if !s.Equal(ast.NewNot(ast.NewZAny())) { t.Fatalf("Expected EmptySet, but got %s", s) } } var andNameTelephonePerson = combinator.G{ "main": combinator.InOrder( combinator.AllOf( combinator.InOrder( combinator.Any(), combinator.In("Name", combinator.Value( funcs.StringEq(funcs.StringVar(), funcs.StringConst("David"))), ), combinator.Any(), ), combinator.InOrder( combinator.Any(), combinator.In("Telephone", combinator.Value( funcs.StringEq(funcs.StringVar(), funcs.StringConst("0123456789"))), ), combinator.Any(), ), ), ), } func TestSimplify2(t *testing.T) {