-
Notifications
You must be signed in to change notification settings - Fork 0
/
gfile.ml
99 lines (73 loc) · 2.7 KB
/
gfile.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
open Graph
open Printf
type path = string
(* Format of text files: lines of the form
*
* v id (node with the given identifier)
* e label id1 id2 (arc with the given (string) label. Goes from node id1 to node id2.)
*
*)
(*-------------------------------------------------*)
let write_file path graph =
(* Open a write-file. *)
let ff = open_out path in
(* Write in this file. *)
fprintf ff "=== Graph file ===\n\n" ;
(* Write all nodes *)
v_iter graph (fun id _ -> fprintf ff "v %s\n" id) ;
fprintf ff "\n" ;
(* Write all arcs *)
v_iter graph (fun id out -> List.iter (fun (id2, lbl) -> fprintf ff "e \"%s\" %s %s\n" lbl id id2) out) ;
fprintf ff "\n=== End of graph ===\n" ;
close_out ff ;
()
(*--------------------------------------------------------------------------*)
(* Reads a line with a node. *)
let read_node graph line =
try Scanf.sscanf line "v %s" (fun id -> add_node graph id)
with e ->
Printf.printf "Cannot read node in line - %s:\n%s\n" (Printexc.to_string e) line ;
failwith "from_file"
(* Reads a line with an arc. *)
let read_arc graph line =
try Scanf.sscanf line "e \"%s@\" %s %s" (fun label id1 id2 -> add_arc graph id1 id2 label)
with e ->
Printf.printf "Cannot read arc in line - %s:\n%s\n" (Printexc.to_string e) line ;
failwith "from_file"
(*--------------------------------------------------------------------------*)
let from_file path =
let infile = open_in path in
(* Read all lines until end of file. *)
let rec loop graph =
try
let line = input_line infile in
let graph2 =
(* Ignore empty lines *)
if line = "" then graph
(* The first character of a line determines its content : v or e.
* Lines not starting with v or e are ignored. *)
else match line.[0] with
| 'v' -> read_node graph line
| 'e' -> read_arc graph line
| _ -> graph
in
loop graph2
with End_of_file -> graph
in
let final_graph = loop empty_graph in
close_in infile ;
final_graph
(*--------------------------------------------------------------------------*)
let export path graph =
(* Open a write-file. *)
let ff = open_out path in
(* Write in this file. *)
fprintf ff "digraph finite_state_machine {\n" ;
fprintf ff " rankdir=LR;\n" ;
fprintf ff " size=\"8,5\"\n" ;
fprintf ff " node [shape = circle];\n";
(* Write all arcs *)
v_iter graph (fun id out -> List.iter (fun (id2, lbl) -> fprintf ff " %s -> %s [ label = \"%s\" ]; \n" id id2 lbl) out) ;
fprintf ff "}" ;
close_out ff ;
()