-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathNFA.java
127 lines (115 loc) · 3.54 KB
/
NFA.java
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
import javax.lang.model.element.UnknownElementException;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class NFA {
private static int i;
private Object startState = new Object();
private List<Object> finalStates = new ArrayList<>();
private List<Object> states = new ArrayList<>();
private HashMap<Object, List<Map.Entry<Character, Object>>> transitions = new HashMap<>();
private static Lock lock = new ReentrantLock();
private static Condition c = lock.newCondition();
NFA() {
makeStart();
}
void makeStart() {
startState = i++;
states.add(startState);
}
Object newState() {
int state = i++;
states.add(state);
return state;
}
void newTransition(Object start, char c, Object end) {
if (start == null || end == null ||
!states.contains(start) || !states.contains(end)) {
throw new UnsupportedOperationException("states don't exist!");
} else if ((c < 'a' || c > 'z') && c != '#') {
throw new UnsupportedOperationException("character " + c + " don't support!");
} else {
Map.Entry<Character, Object> t = Map.entry(c, end);
List<Map.Entry<Character, Object>> trans = transitions.get(start);
if (trans == null) {
trans = new ArrayList<>();
}
trans.add(t);
transitions.put(start, trans);
}
}
void makeFinal(Object s) {
finalStates.add(s);
}
NFA(Regex re) {
if (re instanceof ROr) {
ROr or = (ROr) re;
makeStart();
NFA l = new NFA(or.left);
NFA r = new NFA(or.right);
states.addAll(l.states);
states.addAll(r.states);
transitions.putAll(l.transitions);
transitions.putAll(r.transitions);
finalStates.addAll(l.finalStates);
finalStates.addAll(r.finalStates);
newTransition(startState, '#', l.startState);
newTransition(startState, '#', r.startState);
}
if (re instanceof RChar) {
RChar rChar = (RChar) re;
makeStart();
Object f = newState();
newTransition(startState, rChar.c, f);
makeFinal(f);
}
if (re instanceof RSeq) {
RSeq seq = (RSeq) re;
NFA l = new NFA(seq.left);
NFA r = new NFA(seq.right);
startState = l.startState;
finalStates = r.finalStates;
states.addAll(l.states);
states.addAll(r.states);
transitions.putAll(l.transitions);
transitions.putAll(r.transitions);
for (Object o : l.finalStates) {
newTransition(o, '#', r.startState);
}
}
if (re instanceof RStar) {
RStar star = (RStar) re;
makeStart();
makeFinal(startState);
NFA n = new NFA(star.re);
states.addAll(n.states);
transitions.putAll(n.transitions);
newTransition(startState, '#', n.startState);
for (Object o : n.finalStates) {
newTransition(o, '#', startState);
}
}
}
public List<Object> states() {
return states;
}
public Object start_state() {
return startState;
}
public List<Object> final_states() {
return finalStates;
}
public List<Map.Entry<Character, Object>> transition(Object state) {
return transitions.get(state);
}
boolean match(String s, int nthreads) {
ForkJoinPool pool = new ForkJoinPool(nthreads);
LinkedBlockingQueue<String> queue = new LinkedBlockingQueue<>();
queue.add(s+"!"+startState);
boolean r = pool.invoke(new Check(this, new LinkedBlockingQueue<>() , queue));
pool.shutdown();
return r;
}
}