diff --git a/lib/imbecile.rb b/lib/imbecile.rb index 0c6529b..87fb486 100644 --- a/lib/imbecile.rb +++ b/lib/imbecile.rb @@ -1,3 +1,5 @@ +require "erb" +require "set" require_relative "imbecile/cli" require_relative "imbecile/grammar" require_relative "imbecile/regex" @@ -5,7 +7,6 @@ require_relative "imbecile/regex/dfa" require_relative "imbecile/regex/nfa" require_relative "imbecile/regex/unit" require_relative "imbecile/version" -require "erb" module Imbecile diff --git a/lib/imbecile/regex/dfa.rb b/lib/imbecile/regex/dfa.rb index 53db7e9..cbdefa1 100644 --- a/lib/imbecile/regex/dfa.rb +++ b/lib/imbecile/regex/dfa.rb @@ -4,6 +4,34 @@ module Imbecile class DFA def initialize(nfas) + start_nfa = NFA.new + nfas.each do |nfa| + start_nfa.start_state.add_transition(nil, nfa.start_state) + end + nil_transition_states = nil_transition_states(start_nfa.start_state) + end + + private + + # Determine the set of states that can be reached by nil transitions + # from the given state. + # + # @return [Set] + # Set of states. + def nil_transition_states(state) + states = Set[state] + analyze_state = lambda do |state| + state.transitions.each do |range, dest_state| + if range.nil? + unless states.include?(dest_state) + states << dest_state + analyze_state[dest_state] + end + end + end + end + analyze_state[state] + states end end diff --git a/lib/imbecile/regex/nfa.rb b/lib/imbecile/regex/nfa.rb index c115692..fbbbe55 100644 --- a/lib/imbecile/regex/nfa.rb +++ b/lib/imbecile/regex/nfa.rb @@ -6,6 +6,7 @@ module Imbecile class State attr_accessor :accepts + attr_reader :transitions def initialize @transitions = []