-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathdfa.ts
54 lines (40 loc) · 1.16 KB
/
dfa.ts
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
import { Map, Set } from 'immutable';
import { Re, Class, NONE, EMPTY } from './re';
import { Derivatives, isNullable } from './derivatives';
export type Transitions = Map<number, Class | null>;
export type Dfa = Map<number, Transitions>;
export function toDfa(re: Re): Dfa {
let regexps = Map<Re, number>().asMutable();
return Map<number, Transitions>().withMutations(dfa => {
(function getIndex(re: Re): number {
if (re.equals(NONE)) {
return -1;
}
if (re.type === 'Empty') {
return -2;
}
let index = regexps.get(re);
if (index !== undefined) {
return index;
}
index = regexps.size;
regexps.set(re, index);
let derivatives = Derivatives.fromRe(re);
dfa.set(
index,
Map<number, Class | null>().withMutations(map => {
for (let [re, chars] of derivatives.items) {
map.set(getIndex(re), chars);
}
map.set(getIndex(derivatives.rest), null);
let finalRe = getIndex(isNullable(re) ? EMPTY : NONE);
let existingClass = map.get(finalRe, Set<number>());
if (existingClass !== null) {
map.set(finalRe, existingClass.add(-1));
}
})
);
return index;
})(re);
});
}