// 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 }
// showgrid prints a table matching exprs with specimens (skipping duplicates). // A DRAWLINE line in the list draws a horizontal separator in the table func showgrid(w http.ResponseWriter, dfa *rx.DFA, nexpr int, trylist []string) { seen := make(map[string]bool, 0) fmt.Fprintf(w, "<TABLE>\n<TR>") for i := 0; i < nexpr; i++ { fmt.Fprintf(w, "<TH class=%s>%c</TH>", colorname(i), rx.AcceptLabels[i]) } fmt.Fprintf(w, "<TH class=\"cg leftb\">example</TH></TR>\n") drawline := true for _, s := range trylist { if s == DRAWLINE { drawline = true } else if !seen[s] { seen[s] = true if drawline { fmt.Fprintf(w, "<TR class=topsep>") drawline = false } else { fmt.Fprintf(w, "<TR>") } aset := dfa.Accepts(s) if aset == nil { aset = &rx.BitSet{} } n := 0 e := -1 for i := 0; i < nexpr; i++ { if aset.Test(i) { n++ e = i fmt.Fprintf(w, // highlighted checkmark "<TD class=%s>\u2713</TD>", colorname(i)) } else { fmt.Fprintf(w, "<TD>\u2013</TD>") // - } } class := "cg" switch n { case 0: class = "error" case 1: class = fmt.Sprintf("%s", colorname(e)) case nexpr: class = "cw" } fmt.Fprintf(w, "<TD class=\"leftb %s\">%s</TD></TR>\n", class, hx(s)) } } fmt.Fprintf(w, "</TABLE>\n") }
// synthx generates and prints synthetic examples from a DFA. func synthx(dfa *rx.DFA) { _, isMulti := dfa.Tree.(*rx.AltNode) // true if MultiDFA synthx := dfa.Synthesize() // synthesize examples rx.ShowLabel(os.Stdout, "Examples from DFA") for _, x := range synthx { fmt.Printf("s%d: %s", x.State, rx.Protect(x.Example)) if isMulti { fmt.Printf(" %s\n", x.RXset) } else { fmt.Println() } } }
// print NFA and DFA, with buttons linking to display page func showaut(w http.ResponseWriter, dfa *rx.DFA, exprlist []string) { fmt.Fprintln(w, `<div><div class=lfloat>`) nfaBuffer := &bytes.Buffer{} dfa.ShowNFA(nfaBuffer, "") fmt.Fprintf(w, "<h2>NFA</h2><PRE class=smaller>\n%s</PRE>\n", hx(string(nfaBuffer.Bytes()))) formlink(w, "/drawNFA", exprlist, "Draw the graph") fmt.Fprintln(w, `</div><div class=lstripe>`) dfaBuffer := &bytes.Buffer{} dfa.ShowStates(dfaBuffer, "") fmt.Fprintf(w, "<h2 class=noadvance>DFA</h2><PRE class=smaller>\n%s</PRE>\n", hx(string(dfaBuffer.Bytes()))) formlink(w, "/drawDFA", exprlist, "Draw the graph") fmt.Fprintln(w, `</div></div><div class=reset></div>`) }
// examples generates a line's worth of examples with max replication n. // Each example is also tested against the DFA. func examples(dfa *rx.DFA, tree rx.Node, n int) { s := fmt.Sprintf("ex(%d):", n) nprinted := 0 fmt.Print(s) ncolm := utf8.RuneCountInString(s) for { s := rx.Specimen(tree, n) t := rx.Protect(s) ncolm += 2 + utf8.RuneCountInString(t) if nprinted > 0 && ncolm > linemax { break } fmt.Printf(" %s", t) if dfa.Accepts(s) == nil { fmt.Print(" [FAIL]") ncolm += 7 } nprinted++ } fmt.Println() }