pattern_compiler/cfg/
generate_dot.rs

1use std::io::Write;
2
3use ::petgraph::Direction;
4use ::petgraph::visit::EdgeRef;
5
6use ::cfg::{ PatternCfg, CfgNodeKind };
7use ::pattern::PatternProvider;
8
9const DOT_BREAK: &str = "<br align=\"left\" />";
10
11fn format_label(label: &str) -> String {
12    label.replace("{", "\\{").replace("}", "\\}").replace("\n", DOT_BREAK)
13}
14
15impl<P> PatternCfg<P> where P: PatternProvider {
16
17    pub fn to_dot(&self, w: &mut Write) -> ::std::io::Result<()> {
18
19        write!(w, "digraph g {{\n")?;
20        write!(w, "node [labeljust=\"l\", shape=record, fontname=\"Courier New\"]\n")?;
21        write!(w, "edge [fontname=\"Courier New\" ]\n\n")?;
22
23        for index in self.graph.node_indices() {
24            let node = &self.graph[index];
25            println!("{:?}", node);
26
27            let label = format_label(&format!("{:?}", node));
28            write!(w, "node_{} [ label=<{}: {}", index.index(), index.index(), label)?;
29
30            if let CfgNodeKind::Leaf(leaf_id) = *node {
31                let bindings = &self.leaf_bindings[&self.leaves[&leaf_id]];
32                write!(w, "{} {}", DOT_BREAK, format_label(&format!("{:#?}", bindings)))?;
33            }
34
35            write!(w, "> ]\n")?;
36
37            for edge in self.graph.edges_directed(index, Direction::Outgoing) {
38                let label = format_label(&format!("{:?}", edge.weight()));
39                write!(w, "node_{} -> node_{} [ label=<{}> ]\n",
40                       edge.source().index(), edge.target().index(), label)?;
41            }
42
43            write!(w, "\n")?;
44        }
45
46        write!(w, "}}\n")?;
47        Ok(())
48    }
49
50}
51