def reparse( text )
stack = Main.new
current = stack
offset = 0
finished = false
until finished
mode = nil
match = nil
token = nil
index = text.length
unless stack.empty?
raise "not a marker on end of stack?" unless Marker === stack.last
m = stack.last
t = m.token
i = text.index( t.stop( m.match ), offset )
if i
mode = :END
token = t
match = $~
index = i
end
end
@registry.each do |t|
i = text.index( t.start( current.match ), offset )
if i and i < index
m = $~
mode = t.unit? ? :UNIT : :START
token = t
match = m
index = i
unless t.unit?
unless text.index( t.stop( m ), m.end(0) )
raise "no end token matching #{t.stop( m )}"
end
end
end
end
case mode
when :START
buffer_text = text[offset...index]
current << buffer_text unless buffer_text.empty?
mock = Marker.new
mock.token = token
mock.match = match
mock.parent = current
current << mock
current = mock
stack << mock
offset = match.end(0)
when :END
buffer_text = text[offset...index].chomp("\n")
current << buffer_text unless buffer_text.empty?
mock = stack.pop
mock.outer_range = mock.match.begin(0)...match.end(0)
mock.inner_range = mock.match.end(0)...match.begin(0)
current = mock.parent
offset = match.end(0)
when :UNIT
buffer_text = text[offset...index]
current << buffer_text unless buffer_text.empty?
mock = Marker.new
mock.token = token
mock.match = match
mock.parent = current
mock.outer_range = match.begin(0)...match.end(0)
current << mock
offset = match.end(0)
else
buffer_text = text[offset..-1].chomp("\n")
current << buffer_text unless buffer_text.empty?
finished = true
end
end
return stack
end