// Returns a generator that will run the generator for r's sub-expression [min, max] times. func createRepeatingGenerator(regexp *syntax.Regexp, genArgs *GeneratorArgs, min, max int) (*internalGenerator, error) { if err := enforceSingleSub(regexp); err != nil { return nil, err } generator, err := newGenerator(regexp.Sub[0], genArgs) if err != nil { return nil, generatorError(err, "failed to create generator for subexpression: /%s/", regexp) } if min == noBound { min = int(genArgs.MinUnboundedRepeatCount) } if max == noBound { max = int(genArgs.MaxUnboundedRepeatCount) } return &internalGenerator{regexp.String(), func() string { n := min + genArgs.rng.Intn(max-min+1) var result bytes.Buffer for i := 0; i < n; i++ { result.WriteString(generator.Generate()) } return result.String() }}, nil }
func opConcat(regexp *syntax.Regexp, genArgs *GeneratorArgs) (*internalGenerator, error) { enforceOp(regexp, syntax.OpConcat) generators, err := newGenerators(regexp.Sub, genArgs) if err != nil { return nil, generatorError(err, "error creating generators for concat pattern /%s/", regexp) } return &internalGenerator{regexp.String(), func() string { return genArgs.Executor.Execute(generators) }}, nil }
func opAlternate(regexp *syntax.Regexp, genArgs *GeneratorArgs) (*internalGenerator, error) { enforceOp(regexp, syntax.OpAlternate) generators, err := newGenerators(regexp.Sub, genArgs) if err != nil { return nil, generatorError(err, "error creating generators for alternate pattern /%s/", regexp) } numGens := len(generators) return &internalGenerator{regexp.String(), func() string { i := genArgs.rng.Intn(numGens) generator := generators[i] return generator.Generate() }}, nil }
func opConcat(regexp *syntax.Regexp, genArgs *GeneratorArgs) (*internalGenerator, error) { enforceOp(regexp, syntax.OpConcat) generators, err := newGenerators(regexp.Sub, genArgs) if err != nil { return nil, generatorError(err, "error creating generators for concat pattern /%s/", regexp) } return &internalGenerator{regexp.String(), func() string { var result bytes.Buffer for _, generator := range generators { result.WriteString(generator.Generate()) } return result.String() }}, nil }
// Returns a generator that will run the generator for r's sub-expression [min, max] times. func createRepeatingGenerator(regexp *syntax.Regexp, genArgs *GeneratorArgs, min int, max int) (*internalGenerator, error) { if err := enforceSingleSub(regexp); err != nil { return nil, err } generator, err := newGenerator(regexp.Sub[0], genArgs) if err != nil { return nil, generatorError(err, "failed to create generator for subexpression: /%s/", regexp) } if max < 0 { max = maxUpperBound } return &internalGenerator{regexp.String(), func() string { n := min + genArgs.rng.Intn(max-min+1) return executeGeneratorRepeatedly(genArgs.Executor, generator, n) }}, nil }
func opCapture(regexp *syntax.Regexp, args *GeneratorArgs) (*internalGenerator, error) { enforceOp(regexp, syntax.OpCapture) if err := enforceSingleSub(regexp); err != nil { return nil, err } groupRegexp := regexp.Sub[0] generator, err := newGenerator(groupRegexp, args) if err != nil { return nil, err } // Group indices are 0-based, but index 0 is the whole expression. index := regexp.Cap - 1 return &internalGenerator{regexp.String(), func() string { return args.CaptureGroupHandler(index, regexp.Name, groupRegexp, generator, args) }}, nil }
// CompileSyntax is like Compile but takes a syntax tree as input. func CompileSyntax(ast *syntax.Regexp) (*Regexp, error) { return compileSyntax(ast, ast.String(), true) }
// Generator that does nothing. func noop(regexp *syntax.Regexp, args *GeneratorArgs) (*internalGenerator, error) { return &internalGenerator{regexp.String(), func() string { return "" }}, nil }
// Handles syntax.ClassNL because the parser uses that flag to generate character // classes that respect it. func opCharClass(regexp *syntax.Regexp, args *GeneratorArgs) (*internalGenerator, error) { enforceOp(regexp, syntax.OpCharClass) charClass := parseCharClass(regexp.Rune) return createCharClassGenerator(regexp.String(), charClass, args) }
func opAnyCharNotNl(regexp *syntax.Regexp, args *GeneratorArgs) (*internalGenerator, error) { enforceOp(regexp, syntax.OpAnyCharNotNL) charClass := newCharClass(1, rune(math.MaxInt32)) return createCharClassGenerator(regexp.String(), charClass, args) }
func opAnyChar(regexp *syntax.Regexp, args *GeneratorArgs) (*internalGenerator, error) { enforceOp(regexp, syntax.OpAnyChar) return &internalGenerator{regexp.String(), func() string { return runesToString(rune(args.rng.Int31())) }}, nil }
func opLiteral(regexp *syntax.Regexp, args *GeneratorArgs) (*internalGenerator, error) { enforceOp(regexp, syntax.OpLiteral) return &internalGenerator{regexp.String(), func() string { return runesToString(regexp.Rune...) }}, nil }
func opEmptyMatch(regexp *syntax.Regexp, args *GeneratorArgs) (*internalGenerator, error) { enforceOp(regexp, syntax.OpEmptyMatch) return &internalGenerator{regexp.String(), func() string { return "" }}, nil }