// small util that turn a regexp into a graphiz .dot file and then into a png func main() { exp := os.Args[1] fmt.Printf("Parsing %s\n", exp) var m gogrex.StringManager g, err := gogrex.ParseGrex(&m, exp) if err != nil { fmt.Printf("error %s", err) } fmt.Printf("\n%s\n", g.String()) err = ioutil.WriteFile("graph.dot", []byte(g.String()), 0644) if err != nil { panic(err) } dot("graph.dot") }
//computes all that is needed for this neobin func compile(n *neobin) (m *neobinManager, err error) { // parse the expression using grex m = &neobinManager{neobin: n} n.grex, err = gogrex.ParseGrex(m, n.Expression) // build state name // start with the input one name := "State" if m.neobin.Name != nil { name = *m.neobin.Name } in := m.InputState() in.State = name in.Input = true // for every one declared in the states section: for _, s := range n.States { vertex := m.StateByPath(s.Path) vertex.Path = s.Path vertex.State = s.State } // copy src and dest into the transitionEdge for edge, bounds := range n.grex.Edges() { t := edge.(*transitionEdge) t.source = bounds.Start().(*state) t.dest = bounds.End().(*state) } // mark outputs as so for _, s := range n.grex.OutputVertice() { st := s.(*state) st.Output = true } v := n.grex.Vertices() m.neobin.States = make([]*state, len(v)) for i, st := range v { s := st.(*state) m.neobin.States[i] = s } // parse all state, then all transitions for _, s := range m.States() { //s := st.(*state) outEdges := n.grex.OutputEdges(s) //sort outEdges first sort.Sort(ByName{outEdges}) s.Transitions = make([]*transitionEdge, len(outEdges)) for i, v := range outEdges { t := v.(*transitionEdge) s.Transitions[i] = t } //mark the boolean choice s.Choice = len(outEdges) > 1 // run the state template if err != nil { panic(err) } var id int // the unique id for the transition for _, t := range s.Transitions { t.Id = id id++ if err != nil { panic(err) } } } return }