-
Notifications
You must be signed in to change notification settings - Fork 97
Expand file tree
/
Copy pathnfa_simulation.rb
More file actions
38 lines (31 loc) · 1021 Bytes
/
Copy pathnfa_simulation.rb
File metadata and controls
38 lines (31 loc) · 1021 Bytes
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
require_relative 'dfa_design'
require_relative 'dfa_rulebook'
require_relative 'fa_rule'
require 'set'
class NFASimulation < Struct.new(:nfa_design)
def next_state(state, character)
nfa_design.to_nfa(state).tap { |nfa|
nfa.read_character(character)
}.current_states
end
def rules_for(state)
nfa_design.rulebook.alphabet.map { |character|
FARule.new(state, character, next_state(state, character))
}
end
def discover_states_and_rules(states)
rules = states.flat_map { |state| rules_for(state) }
more_states = rules.map(&:follow).to_set
if more_states.subset?(states)
[states, rules]
else
discover_states_and_rules(states + more_states)
end
end
def to_dfa_design
start_state = nfa_design.to_nfa.current_states
states, rules = discover_states_and_rules(Set[start_state])
accept_states = states.select { |state| nfa_design.to_nfa(state).accepting? }
DFADesign.new(start_state, accept_states, DFARulebook.new(rules))
end
end