// details responds to an inspection request for a single expression func details(w http.ResponseWriter, r *http.Request) { field := fmt.Sprintf("v%d", baseExpr) expr := r.FormValue(field) // must read before any writing expr = strings.TrimSpace(expr) // trim leading/trailing blanks putheader(w, r, "Inspect Expression") tree, err := rx.Parse(expr) if err == nil { fmt.Fprintf(w, "<P>Regular Expression: %s\n", hx(expr)) // must print (or at least stringize) tree before augmenting fmt.Fprintf(w, "<P>Initial Parse Tree: %s\n", hx(tree)) augt := rx.Augment(tree, 0) dfa := rx.BuildDFA(augt) dmin := dfa.Minimize() fmt.Fprintf(w, "<P>Augmented Tree: %s\n", hx(augt)) fmt.Fprintf(w, "<h2>Examples</h2>\n<P>") genexamples(w, tree, 0) genexamples(w, tree, 1) genexamples(w, tree, 2) genexamples(w, tree, 3) genexamples(w, tree, 5) genexamples(w, tree, 8) showaut(w, dmin, []string{expr}) } else { fmt.Fprint(w, "<P>") showerror(w, err) } fmt.Fprint(w, "<h2>Try another?</h2>") putform(w, "/details", "Enter a regular expression:", 1, []string{expr}, 0, nil) putfooter(w, r) }
// multaut displays a multi-NFA and multi-DFA func multaut(w http.ResponseWriter, r *http.Request) { // must read all input before writing anything exprlist := getexprs(r) nx := len(exprlist) // parse and echo the input treelist := make([]rx.Node, 0, nx) putheader(w, r, "Multi-expression Automata") fmt.Fprintf(w, "<P class=xleading>%d expressions:\n", nx) for i, s := range exprlist { fmt.Fprintf(w, "<BR><B>%c:</B> %s\n", rx.AcceptLabels[i], hx(s)) tree, err := rx.Parse(s) if !showerror(w, err) { treelist = append(treelist, rx.Augment(tree, i)) } } if nx > 0 && len(treelist) == nx { // if no errors dfa := rx.MultiDFA(treelist) // build combined DFA dmin := dfa.Minimize() showaut(w, dmin, exprlist) } putfooter(w, r) }
// lpxc -- list and parse expressions for comparison, returning augtree list func lpxc(w http.ResponseWriter, exprlist []string) []rx.Node { treelist := make([]rx.Node, 0) for i, s := range exprlist { fmt.Fprintf(w, "<SPAN class=%s><BR><B>%c:</B> %s</SPAN>\n", colorname(i), rx.AcceptLabels[i], hx(s)) tree, err := rx.Parse(s) if !showerror(w, err) { treelist = append(treelist, rx.Augment(tree, i)) } } return treelist }
// draw produces a Dot file for rendering a DFA or NFA in the user's browser. func draw(w http.ResponseWriter, r *http.Request, which string) { exprlist := getexprs(r) // must load data before writing anything nx := len(exprlist) putheader(w, r, which+" Graph") // write page header fmt.Fprintln(w, "<P class=xleading>") treelist := make([]rx.Node, 0) for i, e := range exprlist { if nx > 1 { fmt.Fprintf(w, "%c. ", rx.AcceptLabels[i]) } fmt.Fprintf(w, "%s<BR>\n", hx(e)) tree, err := rx.Parse(e) if !showerror(w, err) { treelist = append(treelist, rx.Augment(tree, i)) } } if nx > 0 && len(treelist) == nx { // if no errors dfa := rx.MultiDFA(treelist) // build combined DFA dmin := dfa.Minimize() // minimize it fmt.Fprintln(w, `<script type="text/vnd.graphviz" id="graph">`) if which == "NFA" { dmin.GraphNFA(w, "") } else if nx == 1 { dmin.ToDot(w, "", "") } else { which = "Multi" dmin.ToDot(w, "", rx.AcceptLabels) } fmt.Fprintln(w, `</script>`) tDraw.Execute(w, which) } putfooter(w, r) }
// refexamine advertises the Examine page func refexamine(w http.ResponseWriter) { fmt.Fprint(w, ` <P> On the <A HREF="/examine">Examine</A> page you can enter a regular expression to generate several kinds of data: parse trees, synthetic examples, and the automata state lists. Links from there produce diagrams of either the <A HREF="http://en.wikipedia.org/wiki/Nondeterministic_finite_automaton">NFA</A> or <A HREF="http://en.wikipedia.org/wiki/Deterministic_finite_automaton">DFA</A> for the language. `) tree, _ := rx.Parse(HomeExample) augt := rx.Augment(tree, 0) fmt.Fprintf(w, ` <DIV CLASS=inblock>Regular Expression: %s <BR>Augmented Parse Tree: %s <BR class=xleading>Examples:<BR>`, hx(HomeExample), hx(augt)) genexamples(w, augt, 0) genexamples(w, augt, 2) genexamples(w, augt, 4) fmt.Fprintln(w, `<DIV class="rside smaller">`) genexam(w, "submit this example to see full output", HomeExample) fmt.Fprintln(w, `</DIV></DIV>`) }