-
Notifications
You must be signed in to change notification settings - Fork 0
/
reg.rb
59 lines (53 loc) · 1.17 KB
/
reg.rb
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
require 'nfa'
class REG
def initialize(exp)
@nfa = nfa(exp.split(''))
end
def run(input)
@nfa.run input
end
private
def nfa(exp)
stack = [[]]
for i in exp
if i == '('
stack.push []
elsif i == ')'
sub_exp = stack.pop
stack[-1] << nfa(sub_exp)
else
stack[-1] << i
end
end
for i in 0...stack[-1].length
stack[-1][i] = NFA.new stack[-1][i] unless stack[-1][i].is_a? NFA or stack[-1][i] == '|' or stack[-1][i] == '*'
end
while stack[-1].include? '*'
index = stack[-1].index('*')
stack[-1][index-1].star!
stack[-1].delete_at(index)
end
i = 0
while i < stack[-1].length - 1
unless stack[-1][i+1] == '|' or stack[-1][i] == '|'
stack[-1][i] = stack[-1][i].concat stack[-1][i+1]
stack[-1].delete_at(i+1)
else
i = i + 1
end
end
result = stack[-1][0]
for i in 1...stack[-1].length
if stack[-1][i] != '|'
result = result.union stack[-1][i]
end
end
result
end
end
if $PROGRAM_NAME == __FILE__
r = REG.new '(ab|c)*'
p r.run(%w[a b c a b c])
p r.run(%w[a b c a])
p r.run(%w[c c])
end