Home | History | Annotate | Download | only in antlr3
      1 #!/usr/bin/ruby
      2 # encoding: utf-8
      3 
      4 module ANTLR3
      5 module Util
      6 
      7 module_function
      8   
      9   def snake_case( str )
     10     str = str.to_s.gsub( /([A-Z]+)([A-Z][a-z])/,'\1_\2' )
     11     str.gsub!( /([a-z\d])([A-Z])/,'\1_\2' )
     12     str.tr!( "-", "_" )
     13     str.downcase!
     14     str
     15   end
     16   
     17   def parse_version( version_string )
     18     version_string.split( '.' ).map! do | segment |
     19       segment.to_i
     20     end.freeze
     21   end
     22   
     23   def tidy( here_doc, flow = false )
     24     here_doc.gsub!( /^ *\| ?/, '' )
     25     if flow
     26       here_doc.strip!
     27       here_doc.gsub!( /\s+/, ' ' )
     28     end
     29     return here_doc
     30   end
     31   
     32   def silence_warnings
     33     verbosity, $VERBOSE = $VERBOSE, nil
     34     return yield
     35   ensure
     36     $VERBOSE = verbosity
     37   end
     38   
     39 end
     40 
     41 module ClassMacros
     42 
     43 private
     44   
     45   def shared_attribute( name, *additional_members )
     46     attr_reader name
     47     
     48     additional_writers = additional_members.inject( '' ) do |src, attr|
     49       src << "@#{ attr } = value if @#{ attr }\n"
     50     end
     51     
     52     file, line, = caller[ 1 ].split( ':', 3 )
     53     class_eval( <<-END, file, line.to_i )
     54       def #{ name }= value
     55         @#{ name } = value
     56         
     57         each_delegate do |del|
     58           del.#{ name } = value
     59         end
     60         
     61         #{ additional_writers }
     62       end
     63     END
     64   end
     65   
     66   def abstract( name, message = nil )
     67     message ||= "abstract method -- #{ self.class }::#{ name } has not been implemented"
     68     file, line, = caller[ 1 ].split( ':', 3 )
     69     class_eval( <<-END, file, line.to_i )
     70       def #{ name }( * )
     71         raise TypeError, #{ message.to_s.inspect }
     72       end
     73     END
     74   end
     75   
     76   def deprecate( name, extra_message = nil )
     77     hidden_name = "deprecated_#{ name }"
     78     method_defined?( hidden_name ) and return
     79     
     80     alias_method( hidden_name, name )
     81     private( hidden_name )
     82     
     83     message = "warning: method #{ self }##{ name } is deprecated"
     84     extra_message and message << '; ' << extra_message.to_s
     85     
     86     class_eval( <<-END )
     87       def #{ name }( *args, &block )
     88         warn( #{ message.inspect } )
     89         #{ hidden_name }( *args, &block )
     90       end
     91     END
     92   end
     93   
     94   def alias_accessor( alias_name, attr_name )
     95     alias_method( alias_name, attr_name )
     96     alias_method( :"#{ alias_name }=", :"#{ attr_name }=" )
     97   end
     98 
     99 end
    100 
    101 end
    102 
    103 class Integer
    104 
    105   # Returns the lower of self or x.
    106   #
    107   #   4.at_least(5)  #=> 5
    108   #   6.at_least(5)  #=> 6
    109   #
    110   #   CREDIT Florian Gross
    111 
    112   def at_least( x )
    113     ( self >= x ) ? self : x
    114   end
    115 
    116   # Returns the greater of self or x.
    117   #
    118   #   4.at_most(5)  #=> 4
    119   #   6.at_most(5)  #=> 5
    120   #
    121   #   CREDIT Florian Gross
    122 
    123   def at_most( x )
    124     ( self <= x ) ? self : x
    125   end
    126 
    127   # Returns self if above the given lower bound, or
    128   # within the given lower and upper bounds,
    129   # otherwise returns the the bound of which the
    130   # value falls outside.
    131   #
    132   #   4.bound(3)    #=> 4
    133   #   4.bound(5)    #=> 5
    134   #   4.bound(2,7)  #=> 4
    135   #   9.bound(2,7)  #=> 7
    136   #   1.bound(2,7)  #=> 2
    137   #
    138   #   CREDIT Trans
    139 
    140   def bound( lower, upper=nil )
    141     return lower if self < lower
    142     return self unless upper
    143     return upper if self > upper
    144     return self
    145   end
    146 
    147 end
    148 
    149 
    150 class Range
    151   def covers?( range )
    152     range.first >= first or return false
    153     if exclude_end?
    154       range.exclude_end? ? last >= range.last : last > range.last
    155     else
    156       range.exclude_end? ? last.succ >= range.last : last >= range.last
    157     end
    158   end
    159   
    160   def covered_by?( range )
    161     range.covers?( self )
    162   end
    163   
    164   def overlaps?( range )
    165     range.include?( first ) or include?( range.first )
    166   end
    167   
    168   def disjoint?( range )
    169     not overlaps?( range )
    170   end
    171   
    172 end
    173