-
Notifications
You must be signed in to change notification settings - Fork 0
/
write-automata.sml
executable file
·148 lines (133 loc) · 4.52 KB
/
write-automata.sml
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
structure WriteAutomata
:> WRITE_AUTOMATA
=
struct
fun appSeparated f g l =
(case l of
[] =>
()
| h :: t =>
(
f h;
app (fn x => (g (); f x)) t
))
fun writeAutomaton outs name (count, initial, lastFinalSink, lastFinal, actions, trans, transEos) =
let
fun write str = TextIO.output (outs, str)
fun stateName state =
let
val str = Array.sub (actions, state-1)
in
if str = "" then
"<error>"
else
str
end
fun writeSort sep state =
let
val l =
if state <= lastFinalSink then
["sink:", stateName state]
else if state <= lastFinal then
["final:", stateName state]
else
[]
val l =
if state = initial then
if null l then
["initial"]
else
"initial, " :: l
else
l
in
(case l of
[] => ()
| _ =>
(
write sep;
write "(";
app write l;
write ")"
))
end
fun writeTransEntry rangestart rangeend res =
if res = 0 then
()
else
(
write (Int.toString rangestart);
if rangeend > rangestart then
(
write "-";
write (Int.toString rangeend)
)
else
();
write " => state ";
write (Int.toString res);
writeSort " " res;
write "\n"
)
fun writeTrans arr sz rangestart res i =
if i >= sz then
writeTransEntry rangestart (sz-1) res
else
let
val res' = Array.sub (arr, i)
in
if res = res' then
writeTrans arr sz rangestart res (i+1)
else
(
writeTransEntry rangestart (i-1) res;
writeTrans arr sz i res' (i+1)
)
end
fun loop last state =
if state > last then
()
else
(
write "\n-----\n\n";
write name;
write " state ";
write (Int.toString state);
writeSort " " state;
write ":\n\n";
let
val arr = Array.sub (trans, state)
in
writeTrans arr (Array.length arr) 0 (Array.sub (arr, 0)) 1
end;
(case Array.sub (transEos, state) of
0 => ()
| state' =>
(
write "EOS => state ";
write (Int.toString state');
writeSort " " state';
write "\n"
));
loop last (state+1)
)
in
write "Automaton ";
write name;
write "\ninitial state = ";
write (Int.toString initial);
write "\ntotal states = ";
write (Int.toString count);
write "\n";
loop lastFinal (lastFinalSink+1);
loop (count-1) (lastFinal+1)
end
fun writeAutomata outs l =
(
TextIO.output (outs, "AUTOMATON LISTINGS\n==================\n\n");
appSeparated
(fn (name, _, automaton) => writeAutomaton outs name automaton)
(fn () => TextIO.output (outs, "\n=====\n\n"))
l
)
end