class ANTLR3::Rewrite::RewriteProgram
Public Class Methods
new( stream, name = nil )
click to toggle source
# File lib/antlr3/streams/rewrite.rb, line 165 def initialize( stream, name = nil ) @stream = stream @name = name @operations = [] end
Public Instance Methods
clear()
click to toggle source
# File lib/antlr3/streams/rewrite.rb, line 296 def clear @operations.clear end
delete( *range_arguments )
click to toggle source
# File lib/antlr3/streams/rewrite.rb, line 195 def delete( *range_arguments ) range, = cast_range( range_arguments ) op = Delete.new( @stream, range ) @operations << op return op end
execute( *range_arguments )
click to toggle source
# File lib/antlr3/streams/rewrite.rb, line 264 def execute( *range_arguments ) if range_arguments.empty? range = 0 ... @stream.length else range, = cast_range( range_arguments ) end output = '' tokens = @stream.tokens operations = reduce cursor = range.first while range.include?( cursor ) if operation = operations.delete( cursor ) cursor = operation.execute( output ) else token = tokens[ cursor ] output << token.text if token cursor += 1 end end if operation = operations.delete( cursor ) and operation.is_a?( InsertBefore ) # catch edge 'insert-after' operations operation.execute( output ) end return output end
insert_after( index, text )
click to toggle source
# File lib/antlr3/streams/rewrite.rb, line 187 def insert_after( index, text ) index = index.to_i index < 0 and index += @stream.length op = InsertBefore.new( @stream, index + 1, text ) @operations << op return op end
insert_before( index, text )
click to toggle source
# File lib/antlr3/streams/rewrite.rb, line 179 def insert_before( index, text ) index = index.to_i index < 0 and index += @stream.length op = InsertBefore.new( @stream, index, text ) @operations << op return op end
reduce()
click to toggle source
# File lib/antlr3/streams/rewrite.rb, line 202 def reduce operations = @operations.reverse reduced = [] until operations.empty? operation = operations.shift location = operation.location case operation when Replace operations.delete_if do |prior_operation| prior_location = prior_operation.location case prior_operation when InsertBefore location.include?( prior_location ) when Replace if location.covers?( prior_location ) true elsif location.overlaps?( prior_location ) conflict!( operation, prior_operation ) end end end when InsertBefore operations.delete_if do |prior_operation| prior_location = prior_operation.location case prior_operation when InsertBefore if prior_location == location operation.text += prior_operation.text true end when Replace if location == prior_location.first prior_operation.text = operation.text << prior_operation.text.to_s operation = nil break( false ) elsif prior_location.include?( location ) conflict!( operation, prior_operation ) end end end end reduced.unshift( operation ) if operation end @operations.replace( reduced ) @operations.inject( {} ) do |map, operation| other_operaiton = map[ operation.index ] and ANTLR3.bug!( Util.tidy( <<-END ) % [ self.class, operation, other_operaiton ] ) | %s#reduce! should have left only one operation per index, | but %p conflicts with %p END map[ operation.index ] = operation map end end
replace( *range_arguments )
click to toggle source
# File lib/antlr3/streams/rewrite.rb, line 171 def replace( *range_arguments ) range, text = cast_range( range_arguments, 1 ) op = Replace.new( @stream, range, text ) @operations << op return op end
undo( number_of_operations = 1 )
click to toggle source
# File lib/antlr3/streams/rewrite.rb, line 300 def undo( number_of_operations = 1 ) @operations.pop( number_of_operations ) end
Private Instance Methods
cast_range( args, extra = 0 )
click to toggle source
# File lib/antlr3/streams/rewrite.rb, line 309 def cast_range( args, extra = 0 ) single, pair = extra + 1, extra + 2 case check_arguments( args, single, pair ) when single loc = args.shift if loc.is_a?( Range ) first, last = loc.first.to_i, loc.last.to_i loc.exclude_end? and last -= 1 return cast_range( args.unshift( first, last ), extra ) else loc = loc.to_i return cast_range( args.unshift( loc, loc ), extra ) end when pair first, last = args.shift( 2 ).map! { |arg| arg.to_i } if first < 0 and last < 0 first += @stream.length last += @stream.length else last < 0 and last += @stream.length first = first.at_least( 0 ) end return( args.unshift( first .. last ) ) end end
check_arguments( args, min, max )
click to toggle source
# File lib/antlr3/streams/rewrite.rb, line 336 def check_arguments( args, min, max ) n = args.length if n < min raise ArgumentError, "wrong number of arguments (#{ args.length } for #{ min })", caller elsif n > max raise ArgumentError, "wrong number of arguments (#{ args.length } for #{ max })", caller else return n end end
conflict!( current, previous )
click to toggle source
# File lib/antlr3/streams/rewrite.rb, line 304 def conflict!( current, previous ) message = 'operation %p overlaps with previous operation %p' % [ current, previous ] raise( RangeError, message, caller ) end