Add NFA class

Start converting units to NFAs
This commit is contained in:
Josh Holtrop 2021-05-13 00:01:12 -04:00
parent 54cefda186
commit d8dd64d860
2 changed files with 69 additions and 0 deletions

40
lib/imbecile/regex/nfa.rb Normal file
View File

@ -0,0 +1,40 @@
module Imbecile
class Regex
class NFA
class State
def initialize
@transitions = []
end
def add_transition(code_point, destination_state)
@transitions << [code_point, destination_state]
end
end
attr_accessor :start_state
attr_accessor :end_state
def initialize
@start_state = State.new
@end_state = State.new
end
class << self
def empty
nfa = NFA.new
nfa.end_state = nfa.start_state
nfa
end
end
end
end
end

View File

@ -14,6 +14,18 @@ module Imbecile
def method_missing(*args) def method_missing(*args)
@units.__send__(*args) @units.__send__(*args)
end end
def to_nfa
if @units.empty?
NFA.empty
else
@units.map do |unit|
unit.to_nfa
end.reduce do |result, nfa|
result.end_state.add_transition(nil, nfa.start_state)
result
end
end
end
end end
class AlternatesUnit < Unit class AlternatesUnit < Unit
@ -47,6 +59,23 @@ module Imbecile
@alternates[-1] = new_unit @alternates[-1] = new_unit
end end
end end
def to_nfa
if @alternates.size == 0
NFA.empty
elsif @alternates.size == 1
@alternates[0].to_nfa
else
nfa = NFA.new
alternate_nfas = @alternates.map do |alternate|
alternate.to_nfa
end
alternate_nfas.each do |alternate_nfa|
nfa.start_state.add_transition(nil, alternate_nfa.start_state)
alternate_nfa.end_state.add_transition(nil, nfa.end_state)
end
nfa
end
end
end end
class CharacterUnit < Unit class CharacterUnit < Unit