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)
|
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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user