func main() { // get command line options nways := 1 if len(os.Args) == 3 { nways, _ = strconv.Atoi(os.Args[2]) } if len(os.Args) < 2 || len(os.Args) > 3 || nways < 1 { log.Fatal("usage: rxtime exprfile [n]") } filename := os.Args[1] // load expressions from file exprs := rx.LoadExpressions(filename, nil) nexprs := len(exprs) if nways < 1 || nways > nexprs { log.Fatal(fmt.Sprintf( "cannot combine %d expressions(s) in %d way(s)", nexprs, nways)) } // record individual complexity scores and make augmented parse trees cx := make([]int, nexprs) for i, t := range exprs { cx[i] = rx.ComplexityScore(t.Tree) t.Tree = rx.Augment(t.Tree, i) } // initialize index list for first combination {0,1,2...} xlist := make([]int, nways) for i := range xlist { xlist[i] = i } // try all possible n-way combinations by varying the index list tlist := make([]rx.Node, nways) for xlist != nil { for i, x := range xlist { tlist[i] = exprs[x].Tree } _ = rxsys.Interval() // reset timer dfa1 := rx.MultiDFA(tlist) // make DFA t1 := rxsys.Interval().Seconds() // measure time dfa2 := dfa1.Minimize() // minimize DFA t2 := rxsys.Interval().Seconds() // measure time fmt.Printf("%6d %6d %8.3f %8.3f", len(dfa1.Dstates), len(dfa2.Dstates), t1, t2) if nways == 1 { fmt.Printf(" %6d", cx[xlist[0]]) } fmt.Print(" {") for _, x := range xlist { fmt.Printf(" %d", x) } fmt.Print(" }\n") xlist = advance(xlist, nexprs) // get next combination } }
// setup performs global initialization actions func setup() { rxsys.Interval() // initialize timestamps options() // process command-line options if verbose { showopts() // show command options } // handle -P (profiling) option pfname := *val['P'] // profiling filename if pfname != "" { // if set pfile, err := os.Create(pfname) rx.CkErr(err) pprof.StartCPUProfile(pfile) } // set up input scanning if *val['e'] != "" { // if -e specified if len(flag.Args()) > 0 { log.Fatal("-e option precludes reading " + flag.Arg(0)) } input = bufio.NewScanner(bytes.NewReader([]byte(*val['e']))) } else { input = rx.MkScanner(rx.OneInputFile()) } timestamp("init") }
// showDFA performs common actions for individual and merged DFAs // it returns the ultimate (original or minimized) dfa func showDFA(dfa *rx.DFA, treelabel string, showtime bool) *rx.DFA { if *opt['p'] { dfa.ShowTree(os.Stdout, dfa.Tree, treelabel) } if *opt['n'] { dfa.ShowNFA(os.Stdout, "NFA") } if *opt['d'] { dfa.ShowStates(os.Stdout, "Unoptimized DFA") } if !*opt['u'] { if showtime { rxsys.Interval() // reset for timing } dfa = dfa.Minimize() if showtime { timestamp(fmt.Sprintf( "minimize to %d states", len(dfa.Dstates))) } if *opt['d'] { dfa.ShowStates(os.Stdout, "Minimized DFA") } } if *opt['h'] { synthx(dfa) } return dfa }