@@ -33,4 +33,57 @@ def follow_rules_for(state, character)
33
33
def rules_for ( state , character )
34
34
rules . select { |rule | rule . applies_to? ( state , character ) } # select * where
35
35
end
36
- end
36
+ end
37
+
38
+ =begin
39
+ #<struct NFARuleSet rules=[#<FARule 1 --a--> 1>, #<FARule 1 --b--> 1>, #<FARule 1 --b--> 2>,
40
+ #<FARule 2 --a--> 3>, #<FARule 2 --b--> 3>, #<FARule 3 --a--> 4>, #<FARule 3 --b--> 4>]>
41
+ =end
42
+ ruleset = NFARuleSet . new ( [
43
+ FARule . new ( 1 , 'a' , 1 ) , FARule . new ( 1 , 'b' , 1 ) , FARule . new ( 1 , 'b' , 2 ) ,
44
+ FARule . new ( 2 , 'a' , 3 ) , FARule . new ( 2 , 'b' , 3 ) , FARule . new ( 3 , 'a' , 4 ) ,
45
+ FARule . new ( 3 , 'b' , 4 )
46
+ ] )
47
+
48
+ # => #<Set: {1, 2}>
49
+ ruleset . next_states ( Set [ 1 ] , 'b' )
50
+ # => #<Set: {1, 3, 4}>
51
+ ruleset . next_states ( Set [ 1 , 2 , 3 ] , 'a' )
52
+ # => #<Set: {1, 2, 4}>
53
+ ruleset . next_states ( Set [ 1 , 3 ] , 'b' )
54
+
55
+ class NFA < Struct . new ( :current_states , :final_states , :ruleset )
56
+ def accepting?
57
+ ( current_states & final_states ) . any? # set intersection operation is empty?
58
+ end
59
+
60
+ def read_char ( character )
61
+ self . current_states = ruleset . next_states ( current_states , character )
62
+ end
63
+
64
+ def read_string ( str )
65
+ str . chars . each do |character |
66
+ read_char ( character )
67
+ end
68
+ end
69
+ end
70
+
71
+ class NFAMaker < Struct . new ( :start_state , :final_states , :ruleset )
72
+ def make_nfa
73
+ NFA . new ( Set [ start_state ] , final_states , ruleset )
74
+ end
75
+
76
+ def accepts? ( str )
77
+ make_nfa . tap { |nfa | nfa . read_string ( str ) } . accepting?
78
+ end
79
+ end
80
+
81
+ nfa = NFAMaker . new ( 1 , [ 4 ] , ruleset )
82
+ # => true
83
+ nfa . accepts? ( 'bab' )
84
+ # => true
85
+ nfa . accepts? ( 'bababab' )
86
+ # => false
87
+ nfa . accepts? ( 'babababa' )
88
+ # => true
89
+ nfa . accepts? ( 'bababababbbbbb' )
0 commit comments