Add CodePointRange class

This commit is contained in:
josh committed 2021-05-23 17:52:20 -04:00
1 parent 3a1650906e
commit 3987f08cd7
6 files changed
+142 -64

No files matched your search

+21 -11
View File
@@ -24,12 +24,10 @@ module Imbecile
def nil_transition_states
states = Set[self]
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
state.nil_transitions.each do |range, dest_state|
unless states.include?(dest_state)
states << dest_state
analyze_state[dest_state]
end
end
end
@@ -37,6 +35,18 @@ module Imbecile
states
end
def nil_transitions
@transitions.select do |code_point, dest_state|
code_point.nil?
end
end
def cp_transitions
@transitions.select do |code_point, dest_state|
code_point
end
end
end
attr_accessor :start_state
@@ -69,13 +79,13 @@ module Imbecile
visit = lambda do |state|
accepts_s = state.accepts ? " *" : ""
rv += "#{state_id[state]}#{accepts_s}:\n"
state.transitions.each do |range, dest_state|
if range.nil?
state.transitions.each do |code_point_range, dest_state|
if code_point_range.nil?
range_s = "nil"
else
range_s = chr[range.first]
if range.size > 1
range_s += "-" + chr[range.last]
range_s = chr[code_point_range.first]
if code_point_range.size > 1
range_s += "-" + chr[code_point_range.last]
end
end
accepts_s = dest_state.accepts ? " *" : ""
+12 -27
View File
@@ -68,18 +68,19 @@ module Imbecile
end
class CharacterRangeUnit < Unit
attr_accessor :min_code_point
attr_accessor :max_code_point
attr_reader :code_point_range
def initialize(c1, c2 = nil)
@min_code_point = c1.ord
@max_code_point = c2 ? c2.ord : @min_code_point
@code_point_range = CodePointRange.new(c1, c2)
end
def range
@min_code_point..@max_code_point
def first
@code_point_range.first
end
def last
@code_point_range.last
end
def to_nfa
nfa = NFA.new
nfa.start_state.add_transition(range, nfa.end_state)
nfa.start_state.add_transition(@code_point_range, nfa.end_state)
nfa
end
end
@@ -108,32 +109,16 @@ module Imbecile
if @units.empty?
nfa.start_state.add_transition(nil, nfa.end_state)
else
ranges = @units.map(&:range)
code_point_ranges = @units.map(&:code_point_range)
if @negate
ranges = negate_ranges(ranges)
code_point_ranges = CodePointRange.invert_ranges(code_point_ranges)
end
ranges.each do |range|
nfa.start_state.add_transition(range, nfa.end_state)
code_point_ranges.each do |code_point_range|
nfa.start_state.add_transition(code_point_range, nfa.end_state)
end
end
nfa
end
private
def negate_ranges(ranges)
ranges = ranges.sort_by(&:first)
new_ranges = []
last_cp = -1
ranges.each do |range|
if range.first > (last_cp + 1)
new_ranges << ((last_cp + 1)..(range.first - 1))
last_cp = range.last
end
end
if last_cp < 0xFFFFFFFF
new_ranges << ((last_cp + 1)..0xFFFFFFFF)
end
new_ranges
end
end
class MultiplicityUnit < Unit