Esempio n. 1
0
//  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> &nbsp; %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)
}
Esempio n. 2
0
//  load expressions, returning list and augmented parse tree list
func load(filename string) []*RegEx {
	elist := make([]*RegEx, 0) // expression structure list
	rx.LoadExpressions(filename, func(l *rx.RegExParsed) {
		if l.Tree != nil { // if a real expression
			e := &RegEx{}
			e.index = len(elist)
			e.cnum = len(elist)
			e.RegExParsed = *l         // save parse tree
			e.examples = genex(l.Tree) // gen examples unaugmented
			t := rx.Augment(l.Tree, e.index)
			e.dfa = rx.BuildDFA(t) // build DFA
			if verbose {
				fmt.Println()
				showexpr(e)     // show details of expr
				showexamples(e) // show its examples
			}
			elist = append(elist, e)
		}
	})
	if verbose {
		fmt.Printf("\nloaded %d expression(s), ignored %d more\n",
			rx.InputRegExCount, rx.InputErrorCount)
	}
	return elist
}
Esempio n. 3
0
//  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)
}
Esempio n. 4
0
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
	}
}
Esempio n. 5
0
//  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> &nbsp; %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
}
Esempio n. 6
0
File: rxg.go Progetto: proebsting/re
func main() {

	rflag := flag.Bool("R", false, "reproducible output")
	flag.Parse()
	if *rflag {
		rand.Seed(0)
	} else {
		rand.Seed(int64(time.Now().Nanosecond()))
	}

	// load and process regexps
	exprs := make([]*RegEx, 0)
	tlist := make([]rx.Node, 0)
	rx.LoadExpressions(rx.OneInputFile(), func(l *rx.RegExParsed) {
		if l.Err != nil {
			fmt.Fprintln(os.Stderr, l.Err)
		}
		if l.Tree != nil {
			atree := rx.Augment(l.Tree, len(tlist))
			tlist = append(tlist, atree)
			exprs = append(exprs, &RegEx{len(exprs), l.Expr})
		}
	})

	// echo the input with index numbers
	fmt.Print(`{"Expressions":`)
	rx.Jlist(os.Stdout, exprs)
	fmt.Println(",")

	// build the DFA and produce examples
	synthx := rx.MultiDFA(tlist).Synthesize()

	// convert into expected form with int array replacing BitSet
	results := make([]*Example, 0, len(synthx))
	for _, x := range synthx {
		results = append(results,
			&Example{x.State, x.RXset.Members(), x.Example})
	}

	// output the array of synthesized examples
	fmt.Print(`"Examples":`)
	rx.Jlist(os.Stdout, results)
	fmt.Println("}")
}
Esempio n. 7
0
// load expressions, returning list and augmented parse tree list
func load(filename string) ([]*rx.RegExParsed, []rx.Node) {
	errcount := 0                       // error count
	exprs := make([]*rx.RegExParsed, 0) // expression structure list
	trees := make([]rx.Node, 0)         // augmented parse tree list

	rx.LoadExpressions(filename, func(l *rx.RegExParsed) {
		if l.Tree != nil { // if a real expression
			augtree := rx.Augment(l.Tree, len(trees))
			trees = append(trees, augtree)
			exprs = append(exprs, l)
		} else if l.Err != nil { // if erroneous
			errcount++
		} // else is just a comment
	})
	fmt.Printf("%d expressions loaded\n", len(exprs))
	if errcount != 0 {
		fmt.Printf("(%d improper expressions ignored)\n", errcount)
	}
	return exprs, trees
}
Esempio n. 8
0
//  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. &nbsp; ", 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)
}
Esempio n. 9
0
// 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>`)
}
Esempio n. 10
0
// load slurps up expressions, returning list and augmented parse tree list
func load() ([]*rx.RegExParsed, []rx.Node) {
	exprs := make([]*rx.RegExParsed, 0) // expression structure list
	trees := make([]rx.Node, 0)         // augmented parse tree list

	rx.LoadFromScanner(input, func(l *rx.RegExParsed) {
		echo(l, len(exprs))
		if l.Tree != nil { // if a real expression
			image := fmt.Sprintf("%s", l.Tree)
			cx := rx.ComplexityScore(l.Tree)
			augtree := rx.Augment(l.Tree, len(trees))
			trees = append(trees, augtree)
			exprs = append(exprs, l)
			if *opt['i'] {
				individual(l, cx, len(exprs), image, augtree)
			}
		}
	})
	babble("%d expression(s) loaded\n", rx.InputRegExCount)
	if rx.InputErrorCount != 0 && (!errsilent || verbose) {
		fmt.Printf("(%d expression(s) rejected)\n",
			rx.InputErrorCount)
	}
	return exprs, trees
}
Esempio n. 11
0
File: rxx.go Progetto: proebsting/re
func main() {
	args := os.Args
	if len(args) != 3 {
		log.Fatal("usage: rxx efile sfile")
	}
	ename := args[1]
	sfile := rx.MkScanner(args[2])

	labels :=
		"123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
	elist := make([]tester, 0, len(labels))

	// load and compile regexps
	fmt.Println()
	tlist := make([]rx.Node, 0) // list of valid parse trees
	rx.LoadExpressions(ename, func(x *rx.RegExParsed) {
		spec := x.Expr
		ptree := x.Tree
		err := x.Err
		if err != nil {
			fmt.Printf("ERR %s\n", spec)
			elist = append(elist, tester{" ", spec, nil, 0})
		} else if ptree == nil {
			fmt.Printf("    %s\n", spec)
			elist = append(elist, tester{" ", spec, nil, 0})
		} else {
			i := len(tlist)
			if i >= len(labels) {
				log.Fatal("too many regular expressions")
			}
			label := string(labels[i : i+1])
			fmt.Printf("%s:  %s\n", label, spec)
			atree := rx.Augment(ptree, len(tlist))
			tlist = append(tlist, atree)
			elist = append(elist, tester{label, spec, ptree, i})
		}
	})

	dfa := rx.MultiDFA(tlist)
	_ = dfa.Minimize()   // should have no effect
	_ = dfa.Minimize()   // should again have no effect
	dfa = dfa.Minimize() // not necessary, but a good stress test
	dfa = dfa.Minimize() // especially if done more than once

	// read and test candidate strings
	fmt.Println()
	for sfile.Scan() {
		s := string(sfile.Bytes())
		results := dfa.Accepts(s)
		if results == nil {
			results = &rx.BitSet{}
		}
		for _, e := range elist {
			if e.tree == nil {
				fmt.Print(" ")
			} else {
				if results.Test(e.index) {
					fmt.Print(e.label)
				} else {
					fmt.Print("-")
				}
			}
		}
		fmt.Printf("  %s\n", s)
	}
	rx.CkErr(sfile.Err())
}