487
|
1 |
// Thompson Construction (Part 2)
|
|
2 |
|
|
3 |
// some more types abbreviations
|
|
4 |
type NFAtrans = (TState, Char) :=> Set[TState]
|
|
5 |
type eNFAtrans = (TState, Option[Char]) :=> Set[TState]
|
|
6 |
|
|
7 |
|
|
8 |
// for composing an eNFA transition with a NFA transition
|
|
9 |
implicit class RichPF(val f: eNFAtrans) extends AnyVal {
|
|
10 |
def +++(g: NFAtrans) : eNFAtrans =
|
|
11 |
{ case (q, None) => applyOrElse(f, (q, None))
|
|
12 |
case (q, Some(c)) =>
|
|
13 |
applyOrElse(f, (q, Some(c))) | applyOrElse(g, (q, c)) }
|
|
14 |
}
|
|
15 |
|
|
16 |
// sequence of two NFAs
|
|
17 |
def NFA_SEQ(enfa1: NFAt, enfa2: NFAt) : NFAt = {
|
|
18 |
val new_delta : eNFAtrans =
|
|
19 |
{ case (q, None) if enfa1.fins(q) => enfa2.starts }
|
|
20 |
|
|
21 |
eNFA(enfa1.starts, new_delta +++ enfa1.delta +++ enfa2.delta,
|
|
22 |
enfa2.fins)
|
|
23 |
}
|
|
24 |
|
|
25 |
// alternative of two NFAs
|
|
26 |
def NFA_ALT(enfa1: NFAt, enfa2: NFAt) : NFAt = {
|
|
27 |
val Q = TState()
|
|
28 |
val new_delta : eNFAtrans =
|
|
29 |
{ case (Q, None) => enfa1.starts | enfa2.starts }
|
|
30 |
val new_fins = (q: TState) => enfa1.fins(q) || enfa2.fins(q)
|
|
31 |
|
|
32 |
eNFA(Set(Q), new_delta +++ enfa1.delta +++ enfa2.delta,
|
|
33 |
new_fins)
|
|
34 |
}
|
|
35 |
|
|
36 |
// star of a NFA
|
|
37 |
def NFA_STAR(enfa: NFAt) : NFAt = {
|
|
38 |
val Q = TState()
|
|
39 |
val new_delta : eNFAtrans =
|
|
40 |
{ case (Q, None) => enfa.starts
|
|
41 |
case (q, None) if enfa.fins(q) => Set(Q) }
|
|
42 |
|
|
43 |
eNFA(Set(Q), new_delta +++ enfa.delta, Set(Q))
|
|
44 |
}
|