Add NFA class
Start converting units to NFAs
This commit is contained in:
parent
54cefda186
commit
d8dd64d860
40
lib/imbecile/regex/nfa.rb
Normal file
40
lib/imbecile/regex/nfa.rb
Normal 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
|
@ -14,6 +14,18 @@ module Imbecile
|
||||
def method_missing(*args)
|
||||
@units.__send__(*args)
|
||||
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
|
||||
|
||||
class AlternatesUnit < Unit
|
||||
@ -47,6 +59,23 @@ module Imbecile
|
||||
@alternates[-1] = new_unit
|
||||
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
|
||||
|
||||
class CharacterUnit < Unit
|
||||
|
Loading…
x
Reference in New Issue
Block a user