func compileSyntax(re *syntax.Regexp, expr string, longest bool) (*Regexp, error) { maxCap := re.MaxCap() capNames := re.CapNames() re = re.Simplify() prog, err := syntax.Compile(re) if err != nil { return nil, err } regexp := &Regexp{ expr: expr, prog: prog, onepass: compileOnePass(prog), numSubexp: maxCap, subexpNames: capNames, cond: prog.StartCond(), longest: longest, } if regexp.onepass == notOnePass { regexp.prefix, regexp.prefixComplete = prog.Prefix() } else { regexp.prefix, regexp.prefixComplete, regexp.prefixEnd = onePassPrefix(prog) } if regexp.prefix != "" { // TODO(rsc): Remove this allocation by adding // IndexString to package bytes. regexp.prefixBytes = []byte(regexp.prefix) regexp.prefixRune, _ = utf8.DecodeRuneInString(regexp.prefix) } return regexp, nil }
// Create a new generator for r. func newGenerator(regexp *syntax.Regexp, args *GeneratorArgs) (generator *internalGenerator, err error) { simplified := regexp.Simplify() factory, ok := generatorFactories[simplified.Op] if ok { return factory(simplified, args) } return nil, fmt.Errorf("invalid generator pattern: /%s/ as /%s/\n%s", regexp, simplified, inspectRegexpToString(simplified)) }
func TestCompileOnePass(t *testing.T) { var ( p *syntax.Prog re *syntax.Regexp err error ) for _, test := range onePassTests { if re, err = syntax.Parse(test.re, syntax.Perl); err != nil { t.Errorf("Parse(%q) got err:%s, want success", test.re, err) continue } // needs to be done before compile... re = re.Simplify() if p, err = syntax.Compile(re); err != nil { t.Errorf("Compile(%q) got err:%s, want success", test.re, err) continue } onePass = compileOnePass(p) if (onePass == notOnePass) != (test.onePass == notOnePass) { t.Errorf("CompileOnePass(%q) got %v, expected %v", test.re, onePass, test.onePass) } } }