Print out DFA to test

This commit is contained in:
Josh Holtrop 2021-05-25 15:52:47 -04:00
parent 37e1252ded
commit 35ef94dbd3
2 changed files with 32 additions and 2 deletions

View File

@ -44,6 +44,7 @@ module Imbecile
token_def[:regex].nfa.end_state.accepts = token_name token_def[:regex].nfa.end_state.accepts = token_name
end end
dfa = Regex::DFA.new(@tokens.map {|token_name, token_def| token_def[:regex].nfa}) dfa = Regex::DFA.new(@tokens.map {|token_name, token_def| token_def[:regex].nfa})
puts dfa
end end
end end

View File

@ -5,6 +5,8 @@ module Imbecile
class State class State
attr_reader :id
class Transition class Transition
attr_reader :code_point_range attr_reader :code_point_range
@ -12,6 +14,7 @@ module Imbecile
def initialize(code_point_range, destination) def initialize(code_point_range, destination)
@code_point_range = code_point_range @code_point_range = code_point_range
@destination = destination
end end
end end
@ -19,7 +22,8 @@ module Imbecile
attr_accessor :accepts attr_accessor :accepts
attr_reader :transitions attr_reader :transitions
def initialize def initialize(id)
@id = id
@transitions = [] @transitions = []
end end
@ -46,13 +50,35 @@ module Imbecile
end end
end end
def to_s
chr = lambda do |value|
if value < 32 || value > 127
"{#{value}}"
else
value.chr
end
end
rv = ""
@states.each_with_index do |state, state_id|
rv += "#{state_id}:\n"
state.transitions.each do |transition|
range_s = chr[transition.code_point_range.first]
if transition.code_point_range.size > 1
range_s += "-" + chr[transition.code_point_range.last]
end
rv += " #{range_s} => #{transition.destination.id}\n"
end
end
rv
end
private private
def register_nfa_state_set(nfa_state_set) def register_nfa_state_set(nfa_state_set)
unless @nfa_state_sets.include?(nfa_state_set) unless @nfa_state_sets.include?(nfa_state_set)
state_id = @states.size state_id = @states.size
@nfa_state_sets[nfa_state_set] = state_id @nfa_state_sets[nfa_state_set] = state_id
@states << State.new @states << State.new(state_id)
@to_process << nfa_state_set @to_process << nfa_state_set
end end
end end
@ -68,6 +94,9 @@ module Imbecile
end end
result result
end end
dest_nfa_states = dest_nfa_states.reduce(Set.new) do |result, dest_nfa_state|
result + dest_nfa_state.nil_transition_states
end
register_nfa_state_set(dest_nfa_states) register_nfa_state_set(dest_nfa_states)
dest_state = @states[@nfa_state_sets[dest_nfa_states]] dest_state = @states[@nfa_state_sets[dest_nfa_states]]
state.add_transition(subrange, dest_state) state.add_transition(subrange, dest_state)