func TestGenerateTests(t *testing.T) { type test struct { pattern string name string } tests := []test{ {"abcdef", "literal"}, {"[a-z]", "CharClass"}, {"a*", "star"}, {"a?", "quest"}, {"a+", "plus"}, {"(abc|def)", "alternatives"}, {"a{1,3}", "repeat1"}, {"a{0,3}", "repeat2"}, {"ab+c", "concat"}, {"^a", "StartOfText"}, {"^", "StartOfTextEmpty"}, {"a$", "EndOfText"}, {"(?m)^a", "StartOfLine"}, {"(?m)^", "StartOfLineEmpty"}, {"(?m)a$", "EndOfLine"}, {`a\b`, "WordBoundary"}, {`a??`, "lazy1"}, {`a??b`, "lazy2"}, {`a*?`, "lazy3"}, {`a*?b`, "lazy4"}, {`a+?`, "lazy5"}, {`a+?b`, "lazy6"}, {`ab??c`, "lazy7"}, {`(?i)aZ`, "IgnoreCase1"}, {`(?i)[a-z]`, "IgnoreCase2"}, } for _, tst := range tests { nfanode, err := nfa.New(tst.pattern) if err != nil { t.Error(err) } else { node := dfa.NewFromNFA(nfanode) source := GoGenerate(node, "test", "match"+uppercaseInitial(tst.name), "string") err := writeToFile("test/"+strings.ToLower(tst.name)+".go", source) if err != nil { t.Error(err) } } } }
func main() { log.SetFlags(0) output := flag.String("o", "", "Output to file") flag.Usage = func() { fmt.Println(`Usage: re2dfa [options] regexp package.function string|[]byte Options: -o FILE Output to FILE instead of standard output EXAMPLE: re2dfa ^a+$ main.matchAPlus string `) } flag.Parse() if len(flag.Args()) != 3 { flag.Usage() os.Exit(1) } expr := flag.Arg(0) _, err := regexp.Compile(expr) if err != nil { log.Fatal(fmt.Sprintf("invalid regexp: %q", expr)) } pkgfun := strings.Split(flag.Arg(1), ".") if len(pkgfun) != 2 { flag.Usage() os.Exit(1) } pkg := pkgfun[0] fun := pkgfun[1] typ := flag.Arg(2) if !(typ == "string" || typ == "[]byte") { flag.Usage() os.Exit(1) } nfanode, err := nfa.New(expr) if err != nil { log.Fatal(err) } node := dfa.NewFromNFA(nfanode) source := codegen.GoGenerate(node, pkg, fun, typ) if *output == "" { fmt.Println(source) } else { f, err := os.Create(*output) if err != nil { log.Fatal(err) } _, err = f.WriteString(source) if err != nil { log.Fatal(err) } err = f.Close() if err != nil { log.Fatal(err) } } }