mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	* lib/date/delta.rb: merged from date4. [experimental]
* lib/date/delta/parser.*: ditto. * lib/date.rb: followed the above changes. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@24567 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
		
							parent
							
								
									cfed2cefb2
								
							
						
					
					
						commit
						ae3a58e8c5
					
				
					 5 changed files with 810 additions and 1 deletions
				
			
		|  | @ -1,3 +1,11 @@ | |||
| Mon Aug 17 08:31:56 2009  Tadayoshi Funaba  <tadf@dotrb.org> | ||||
| 
 | ||||
| 	* lib/date/delta.rb: merged from date4.  [experimental] | ||||
| 
 | ||||
| 	* lib/date/delta/parser.*: ditto. | ||||
| 
 | ||||
| 	* lib/date.rb: followed the above changes. | ||||
| 
 | ||||
| Mon Aug 17 08:19:03 2009  Tadayoshi Funaba  <tadf@dotrb.org> | ||||
| 
 | ||||
| 	* lib/date/format.rb (strptime): removed \v; since \s includes \v. | ||||
|  |  | |||
							
								
								
									
										18
									
								
								lib/date.rb
									
										
									
									
									
								
							
							
						
						
									
										18
									
								
								lib/date.rb
									
										
									
									
									
								
							|  | @ -194,6 +194,7 @@ | |||
| #     puts secs_to_new_year() | ||||
| 
 | ||||
| require 'date/format' | ||||
| require 'date/delta' | ||||
| 
 | ||||
| # Class representing a date. | ||||
| # | ||||
|  | @ -1336,6 +1337,9 @@ class Date | |||
|   def + (n) | ||||
|     case n | ||||
|     when Numeric; return self.class.new!(@ajd + n, @of, @sg) | ||||
|     when Delta | ||||
|       d = n.__send__(:delta) | ||||
|       return (self >> d.imag) + d.real | ||||
|     end | ||||
|     raise TypeError, 'expected numeric' | ||||
|   end | ||||
|  | @ -1352,8 +1356,11 @@ class Date | |||
|     case x | ||||
|     when Numeric; return self.class.new!(@ajd - x, @of, @sg) | ||||
|     when Date;    return @ajd - x.ajd | ||||
|     when Delta | ||||
|       d = x.__send__(:delta) | ||||
|       return (self << d.imag) - d.real | ||||
|     end | ||||
|     raise TypeError, 'expected numeric or date' | ||||
|     raise TypeError, 'expected numeric' | ||||
|   end | ||||
| 
 | ||||
|   # Compare this date with another date. | ||||
|  | @ -1371,6 +1378,12 @@ class Date | |||
|     case other | ||||
|     when Numeric; return @ajd <=> other | ||||
|     when Date;    return @ajd <=> other.ajd | ||||
|     else | ||||
|       begin | ||||
|         l, r = other.coerce(self) | ||||
|         return l <=> r | ||||
|       rescue NoMethodError | ||||
|       end | ||||
|     end | ||||
|     nil | ||||
|   end | ||||
|  | @ -1385,6 +1398,9 @@ class Date | |||
|     case other | ||||
|     when Numeric; return jd == other | ||||
|     when Date;    return jd == other.jd | ||||
|     else | ||||
|       l, r = other.coerce(self) | ||||
|       return l === r | ||||
|     end | ||||
|     false | ||||
|   end | ||||
|  |  | |||
							
								
								
									
										400
									
								
								lib/date/delta.rb
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										400
									
								
								lib/date/delta.rb
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,400 @@ | |||
| # delta.rb: Written by Tadayoshi Funaba 2004-2009 | ||||
| 
 | ||||
| require 'date' | ||||
| require 'date/delta/parser' | ||||
| 
 | ||||
| class Date | ||||
| 
 | ||||
|   class Delta | ||||
| 
 | ||||
|     include Comparable | ||||
| 
 | ||||
|     UNIT_PREFIXES = { | ||||
|       'yotta'      => Rational(10**24), | ||||
|       'zetta'      => Rational(10**21), | ||||
|       'exa'        => Rational(10**18), | ||||
|       'peta'       => Rational(10**15), | ||||
|       'tera'       => Rational(10**12), | ||||
|       'giga'       => Rational(10**9), | ||||
|       'mega'       => Rational(10**6), | ||||
|       'kilo'       => Rational(10**3), | ||||
|       'hecto'      => Rational(10**2), | ||||
|       'deca'       => Rational(10**1), | ||||
|       'deka'       => Rational(10**1), | ||||
|       'deci'       => Rational(1, 10**1), | ||||
|       'centi'      => Rational(1, 10**2), | ||||
|       'milli'      => Rational(1, 10**3), | ||||
|       'decimilli'  => Rational(1, 10**4), | ||||
|       'centimilli' => Rational(1, 10**5), | ||||
|       'micro'      => Rational(1, 10**6), | ||||
|       'nano'       => Rational(1, 10**9), | ||||
|       'millimicro' => Rational(1, 10**9), | ||||
|       'pico'       => Rational(1, 10**12), | ||||
|       'micromicro' => Rational(1, 10**12), | ||||
|       'femto'      => Rational(1, 10**15), | ||||
|       'atto'       => Rational(1, 10**18), | ||||
|       'zepto'      => Rational(1, 10**21), | ||||
|       'yocto'      => Rational(1, 10**24) | ||||
|     } | ||||
| 
 | ||||
|     IUNITS = { | ||||
|       'year'       => Complex(0, 12), | ||||
|       'month'      => Complex(0, 1) | ||||
|     } | ||||
| 
 | ||||
|     RUNITS = { | ||||
|       'day'        => Rational(1), | ||||
|       'week'       => Rational(7), | ||||
|       'sennight'   => Rational(7), | ||||
|       'fortnight'  => Rational(14), | ||||
|       'hour'       => Rational(1, 24), | ||||
|       'minute'     => Rational(1, 1440), | ||||
|       'second'     => Rational(1, 86400) | ||||
|     } | ||||
| 
 | ||||
|     UNIT_PREFIXES.each do |k, v| | ||||
|       RUNITS[k + 'second'] = v * RUNITS['second'] | ||||
|     end | ||||
| 
 | ||||
|     remove_const :UNIT_PREFIXES | ||||
| 
 | ||||
|     UNITS = {} | ||||
| 
 | ||||
|     IUNITS.each do |k, v| | ||||
|       UNITS[k] = v | ||||
|     end | ||||
| 
 | ||||
|     RUNITS.each do |k, v| | ||||
|       UNITS[k] = v | ||||
|     end | ||||
| 
 | ||||
|     UNITS4KEY = {} | ||||
| 
 | ||||
|     UNITS.each do |k, v| | ||||
|       UNITS4KEY[k] = UNITS4KEY[k + 's'] = v | ||||
|     end | ||||
| 
 | ||||
|     UNITS4KEY['y'] = UNITS4KEY['years'] | ||||
|     UNITS4KEY['yr'] = UNITS4KEY['years'] | ||||
|     UNITS4KEY['yrs'] = UNITS4KEY['years'] | ||||
|     UNITS4KEY['m'] = UNITS4KEY['months'] | ||||
|     UNITS4KEY['mo'] = UNITS4KEY['months'] | ||||
|     UNITS4KEY['mon'] = UNITS4KEY['months'] | ||||
|     UNITS4KEY['mnth'] = UNITS4KEY['months'] | ||||
|     UNITS4KEY['mnths'] = UNITS4KEY['months'] | ||||
|     UNITS4KEY['w'] = UNITS4KEY['weeks'] | ||||
|     UNITS4KEY['wk'] = UNITS4KEY['weeks'] | ||||
|     UNITS4KEY['d'] = UNITS4KEY['days'] | ||||
|     UNITS4KEY['dy'] = UNITS4KEY['days'] | ||||
|     UNITS4KEY['dys'] = UNITS4KEY['days'] | ||||
|     UNITS4KEY['h'] = UNITS4KEY['hours'] | ||||
|     UNITS4KEY['hr'] = UNITS4KEY['hours'] | ||||
|     UNITS4KEY['hrs'] = UNITS4KEY['hours'] | ||||
|     UNITS4KEY['min'] = UNITS4KEY['minutes'] | ||||
|     UNITS4KEY['mins'] = UNITS4KEY['minutes'] | ||||
|     UNITS4KEY['s'] = UNITS4KEY['seconds'] | ||||
|     UNITS4KEY['sec'] = UNITS4KEY['seconds'] | ||||
|     UNITS4KEY['secs'] = UNITS4KEY['seconds'] | ||||
|     UNITS4KEY['ms'] = UNITS4KEY['milliseconds'] | ||||
|     UNITS4KEY['msec'] = UNITS4KEY['milliseconds'] | ||||
|     UNITS4KEY['msecs'] = UNITS4KEY['milliseconds'] | ||||
|     UNITS4KEY['milli'] = UNITS4KEY['milliseconds'] | ||||
|     UNITS4KEY['us'] = UNITS4KEY['microseconds'] | ||||
|     UNITS4KEY['usec'] = UNITS4KEY['microseconds'] | ||||
|     UNITS4KEY['usecs'] = UNITS4KEY['microseconds'] | ||||
|     UNITS4KEY['micro'] = UNITS4KEY['microseconds'] | ||||
|     UNITS4KEY['ns'] = UNITS4KEY['nanoseconds'] | ||||
|     UNITS4KEY['nsec'] = UNITS4KEY['nanoseconds'] | ||||
|     UNITS4KEY['nsecs'] = UNITS4KEY['nanoseconds'] | ||||
|     UNITS4KEY['nano'] = UNITS4KEY['nanoseconds'] | ||||
| 
 | ||||
|     def self.delta_to_dhms(delta) | ||||
|       fr = delta.imag.abs | ||||
|       y,   fr = fr.divmod(12) | ||||
|       m,   fr = fr.divmod(1) | ||||
| 
 | ||||
|       if delta.imag < 0 | ||||
| 	y = -y | ||||
| 	m = -m | ||||
|       end | ||||
| 
 | ||||
|       fr = delta.real.abs | ||||
|       ss,  fr = fr.divmod(SECONDS_IN_DAY) # 4p | ||||
|       d,   ss = ss.divmod(86400) | ||||
|       h,   ss = ss.divmod(3600) | ||||
|       min, s  = ss.divmod(60) | ||||
| 
 | ||||
|       if delta.real < 0 | ||||
| 	d = -d | ||||
| 	h = -h | ||||
| 	min = -min | ||||
| 	s = -s | ||||
|       end | ||||
| 
 | ||||
|       return y, m, d, h, min, s, fr | ||||
|     end | ||||
| 
 | ||||
|     def self.dhms_to_delta(y, m, d, h, min, s, fr) | ||||
|       fr = 0 if fr == 0 | ||||
|       Complex(0, y.to_i * 12 + m.to_i) + | ||||
| 	Rational(d * 86400 + h * 3600 + min * 60 + (s + fr), 86400) # 4p | ||||
|     end | ||||
| 
 | ||||
|     def initialize(delta) | ||||
|       @delta = delta | ||||
|       @__ca__ = {} | ||||
|     end | ||||
| 
 | ||||
|     class << self; alias_method :new!, :new end | ||||
| 
 | ||||
|     def self.new(arg=0, h=0, min=0, s=0) | ||||
|       if Hash === arg | ||||
| 	d = Complex(0) | ||||
| 	arg.each do |k, v| | ||||
| 	  k = k.to_s.downcase | ||||
| 	  unless UNITS4KEY[k] | ||||
| 	    raise ArgumentError, "unknown keyword #{k}" | ||||
| 	  end | ||||
| 	  d += v * UNITS4KEY[k] | ||||
| 	end | ||||
|       else | ||||
| 	d = dhms_to_delta(0, 0, arg, h, min, s, 0) | ||||
|       end | ||||
|       new!(d) | ||||
|     end | ||||
| 
 | ||||
|     UNITS.each_key do |k| | ||||
|       module_eval <<-"end;" | ||||
| 	def self.#{k}s(n=1) | ||||
| 	  new(:d=>n * UNITS['#{k}']) | ||||
| 	end | ||||
|       end; | ||||
|     end | ||||
| 
 | ||||
|     class << self; alias_method :mins, :minutes end | ||||
|     class << self; alias_method :secs, :seconds end | ||||
| 
 | ||||
|     def self.parse(str) | ||||
|       d = begin (@@pa ||= Parser.new).parse(str) | ||||
| 	  rescue Racc::ParseError | ||||
| 	    raise ArgumentError, 'syntax error' | ||||
| 	  end | ||||
|       new!(d) | ||||
|     end | ||||
| 
 | ||||
|     def self.diff(d1, d2) new(d1.ajd - d2.ajd) end | ||||
| 
 | ||||
|     class << self | ||||
| 
 | ||||
|       def once(*ids) # :nodoc: -- restricted | ||||
| 	for id in ids | ||||
| 	  module_eval <<-"end;" | ||||
| 	    alias_method :__#{id.object_id}__, :#{id.to_s} | ||||
| 	    private :__#{id.object_id}__ | ||||
| 	    def #{id.to_s}(*args) | ||||
| 	      @__ca__[#{id.object_id}] ||= __#{id.object_id}__(*args) | ||||
| 	    end | ||||
| 	  end; | ||||
|         end | ||||
|       end | ||||
| 
 | ||||
|       private :once | ||||
| 
 | ||||
|     end | ||||
| 
 | ||||
|     def dhms() self.class.delta_to_dhms(@delta) end | ||||
| 
 | ||||
|     once :dhms | ||||
| 
 | ||||
|     def delta() @delta end | ||||
| 
 | ||||
|     protected :delta | ||||
| 
 | ||||
|     def years() dhms[0] end | ||||
|     def months() dhms[1] end | ||||
|     def days() dhms[2] end | ||||
|     def hours() dhms[3] end | ||||
|     def minutes() dhms[4] end | ||||
|     def seconds() dhms[5] end | ||||
|     def second_fractions() dhms[6] end | ||||
| 
 | ||||
|     alias_method :mins, :minutes | ||||
|     alias_method :secs, :seconds | ||||
|     alias_method :sec_fractions, :second_fractions | ||||
| 
 | ||||
|     RUNITS.each_key do |k| | ||||
|       module_eval <<-"end;" | ||||
| 	def in_#{k}s(u=1) | ||||
| 	  if @delta.imag != 0 | ||||
| 	    raise ArgumentError, "#{k}: #{self} has month" | ||||
| 	  end | ||||
| 	  @delta.real / (u * RUNITS['#{k}']) | ||||
| 	end | ||||
|       end; | ||||
|     end | ||||
| 
 | ||||
|     alias_method :in_mins, :in_minutes | ||||
|     alias_method :in_secs, :in_seconds | ||||
| 
 | ||||
|     def zero?() @delta.zero? end | ||||
|     def nonzero?() unless zero? then self end end | ||||
| 
 | ||||
|     def integer? () @delta.imag == 0 && @delta.real.integer? end | ||||
| 
 | ||||
|     def -@ () self.class.new!(-@delta) end | ||||
|     def +@ () self.class.new!(+@delta) end | ||||
| 
 | ||||
|     def dx_addsub(m, n) | ||||
|       case n | ||||
|       when Numeric; return self.class.new!(@delta.__send__(m, n)) | ||||
|       when Delta; return self.class.new!(@delta.__send__(m, n.delta)) | ||||
|       else | ||||
| 	l, r = n.coerce(self) | ||||
| 	return l.__send__(m, r) | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|     private :dx_addsub | ||||
| 
 | ||||
|     def + (n) dx_addsub(:+, n) end | ||||
|     def - (n) dx_addsub(:-, n) end | ||||
| 
 | ||||
|     def dx_muldiv(m, n) | ||||
|       case n | ||||
|       when Numeric | ||||
| 	return self.class.new!(@delta.__send__(m, n)) | ||||
|       else | ||||
| 	l, r = n.coerce(self) | ||||
| 	return l.__send__(m, r) | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|     private :dx_muldiv | ||||
| 
 | ||||
|     def * (n) dx_muldiv(:*, n) end | ||||
|     def / (n) dx_muldiv(:/, n) end | ||||
| 
 | ||||
|     def dx_conv1(m, n) | ||||
|       if @delta.imag != 0 | ||||
| 	raise ArgumentError, "#{m}: #{self} has month" | ||||
|       end | ||||
|       case n | ||||
|       when Numeric | ||||
| 	return self.class.new!(Complex(@delta.real.__send__(m, n), 0)) | ||||
|       else | ||||
| 	l, r = n.coerce(self) | ||||
| 	return l.__send__(m, r) | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|     private :dx_conv1 | ||||
| 
 | ||||
|     def % (n) dx_conv1(:%, n) end | ||||
| 
 | ||||
|     def div(n) dx_conv1(:div, n) end | ||||
|     def modulo(n) dx_conv1(:modulo, n) end | ||||
|     def divmod(n) [div(n), modulo(n)] end | ||||
| 
 | ||||
|     def quotient(n) | ||||
|       if @delta.imag != 0 | ||||
| 	raise ArgumentError, "quotient: #{self} has month" | ||||
|       end | ||||
|       case n | ||||
|       when Numeric | ||||
| 	return self.class.new!(Complex((@delta.real / n).truncate)) | ||||
|       else | ||||
| 	l, r = n.coerce(self) | ||||
| 	return l.__send__(m, r) | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|     def remainder(n) dx_conv1(:remainder, n) end | ||||
|     def quotrem(n) [quotient(n), remainder(n)] end | ||||
| 
 | ||||
|     def ** (n) dx_conv1(:**, n) end | ||||
|     def quo(n) dx_muldiv(:quo, n) end | ||||
| 
 | ||||
|     def <=> (other) | ||||
|       if @delta.imag != 0 | ||||
| 	raise ArgumentError, "<=>: #{self} has month" | ||||
|       end | ||||
|       case other | ||||
|       when Numeric; return @delta.real <=> other | ||||
|       when Delta;   return @delta.real <=> other.delta.real | ||||
|       else | ||||
| 	begin | ||||
| 	  l, r = other.coerce(self) | ||||
| 	  return l <=> r | ||||
| 	rescue NoMethodError | ||||
| 	end | ||||
|       end | ||||
|       nil | ||||
|     end | ||||
| 
 | ||||
|     def == (other) | ||||
|       case other | ||||
|       when Numeric; return @delta == other | ||||
|       when Delta;   return @delta == other | ||||
|       else | ||||
| 	begin | ||||
| 	  l, r = other.coerce(self) | ||||
| 	  return l == r | ||||
| 	rescue NoMethodError | ||||
| 	end | ||||
|       end | ||||
|       nil | ||||
|     end | ||||
| 
 | ||||
|     def coerce(other) | ||||
|       case other | ||||
|       when Numeric; return other, @delta | ||||
|       else | ||||
| 	super | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|     def eql? (other) Delta === other && self == other end | ||||
|     def hash() @delta.hash end | ||||
| 
 | ||||
|     def dx_conv0(m) | ||||
|       if @delta.imag != 0 | ||||
| 	raise ArgumentError, "#{m}: #{self} has month" | ||||
|       end | ||||
|       @delta.real.__send__(m) | ||||
|     end | ||||
| 
 | ||||
|     private :dx_conv0 | ||||
| 
 | ||||
|     def abs() dx_conv0(:abs) end | ||||
| 
 | ||||
|     def ceil() dx_conv0(:ceil) end | ||||
|     def floor() dx_conv0(:floor) end | ||||
|     def round() dx_conv0(:round) end | ||||
|     def truncate() dx_conv0(:truncate) end | ||||
| 
 | ||||
|     def to_i() dx_conv0(:to_i) end | ||||
|     def to_f() dx_conv0(:to_f) end | ||||
|     def to_r() dx_conv0(:to_r) end | ||||
| 
 | ||||
|     alias_method :to_int, :to_i | ||||
| 
 | ||||
|     def inspect() format('#<%s: %s (%s)>', self.class, to_s, @delta) end | ||||
| 
 | ||||
|     def to_s | ||||
|       format(%(%s(%dd %.02d:%02d'%02d"%03d)%s(%dy %dm)), # ' | ||||
| 	     if @delta.real < 0 then '-' else '+' end, | ||||
| 	     days.abs, hours.abs, mins.abs, secs.abs, sec_fractions.abs * 1000, | ||||
| 	     if @delta.imag < 0 then '-' else '+' end, | ||||
| 	     years.abs, months.abs) | ||||
|     end | ||||
| 
 | ||||
|     def marshal_dump() @delta end | ||||
| 
 | ||||
|     def marshal_load(a) | ||||
|       @delta = a | ||||
|       @__ca__ = {} | ||||
|     end | ||||
| 
 | ||||
|   end | ||||
| 
 | ||||
| end | ||||
							
								
								
									
										301
									
								
								lib/date/delta/parser.rb
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										301
									
								
								lib/date/delta/parser.rb
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,301 @@ | |||
| # | ||||
| # DO NOT MODIFY!!!! | ||||
| # This file is automatically generated by racc 1.4.5 | ||||
| # from racc grammer file "parser.ry". | ||||
| # | ||||
| 
 | ||||
| require 'racc/parser' | ||||
| 
 | ||||
| 
 | ||||
| class Date | ||||
| 
 | ||||
|   class Delta | ||||
| 
 | ||||
|     class Parser < Racc::Parser | ||||
| 
 | ||||
| module_eval <<'..end parser.ry modeval..id43bff5dec9', 'parser.ry', 42 | ||||
| 
 | ||||
|   def lookup(str) | ||||
|     t = str.downcase | ||||
|     k = UNITS4KEY[t] | ||||
|     return [:UNIT, k] if k | ||||
|     return [:AND, nil] if t == 'and' | ||||
|     return [:UNKNOWNWORD, nil] | ||||
|   end | ||||
| 
 | ||||
|   def parse(str) | ||||
|     @q = [] | ||||
|     until str.empty? | ||||
|       case str | ||||
|       when /\A\s+/ | ||||
|       when /\AP(\d+y)?(\d+m)?(\d+d)?t?(\d+h)?(\d+m)?(\d+s)?(\d+w)?/i | ||||
| 	y, m, d, h, min, s, w = | ||||
| 	  [$1, $2, $3, $4, $5, $6, $7].collect{|x| x.to_i} | ||||
| 	y *= UNITS4KEY['years'] | ||||
| 	m *= UNITS4KEY['months'] | ||||
| 	d *= UNITS4KEY['days'] | ||||
| 	h *= UNITS4KEY['hours'] | ||||
| 	min *= UNITS4KEY['minutes'] | ||||
| 	s *= UNITS4KEY['seconds'] | ||||
| 	w *= UNITS4KEY['weeks'] | ||||
| 	@q.push [:DURATION, y + m + d + h + min + s + w] | ||||
|       when /\A\d+/ | ||||
| 	@q.push [:DIGITS, $&.to_i] | ||||
|       when /\A[a-z]+/i | ||||
| 	@q.push lookup($&) | ||||
|       when /\A.|\n/ | ||||
| 	@q.push [$&, $&] | ||||
|       end | ||||
|       str = $' | ||||
|     end | ||||
|     @q.push [false, false] | ||||
|     do_parse | ||||
|   end | ||||
| 
 | ||||
|   def next_token | ||||
|     @q.shift | ||||
|   end | ||||
| 
 | ||||
| ..end parser.ry modeval..id43bff5dec9 | ||||
| 
 | ||||
| ##### racc 1.4.5 generates ### | ||||
| 
 | ||||
| racc_reduce_table = [ | ||||
|  0, 0, :racc_error, | ||||
|  1, 16, :_reduce_none, | ||||
|  1, 17, :_reduce_none, | ||||
|  1, 17, :_reduce_none, | ||||
|  3, 17, :_reduce_4, | ||||
|  3, 17, :_reduce_5, | ||||
|  3, 17, :_reduce_6, | ||||
|  3, 17, :_reduce_7, | ||||
|  3, 17, :_reduce_8, | ||||
|  3, 17, :_reduce_9, | ||||
|  3, 17, :_reduce_10, | ||||
|  2, 17, :_reduce_11, | ||||
|  2, 17, :_reduce_12, | ||||
|  3, 17, :_reduce_13, | ||||
|  2, 18, :_reduce_14, | ||||
|  0, 20, :_reduce_15, | ||||
|  1, 20, :_reduce_none, | ||||
|  1, 19, :_reduce_none ] | ||||
| 
 | ||||
| racc_reduce_n = 18 | ||||
| 
 | ||||
| racc_shift_n = 32 | ||||
| 
 | ||||
| racc_action_table = [ | ||||
|     13,    14,    15,    16,    17,    18,    19,     4,    27,    23, | ||||
|      8,     9,     1,     4,    25,     2,     8,     9,     1,     4, | ||||
|     24,     2,     8,     9,     1,     4,    21,     2,     8,     9, | ||||
|      1,     4,    11,     2,     8,     9,     1,     4,    26,     2, | ||||
|      8,     9,     1,     4,   nil,     2,     8,     9,     1,     4, | ||||
|    nil,     2,     8,     9,     1,   nil,   nil,     2,    13,    14, | ||||
|     15,    16,    17,    18,    19,    13,    14,    15,    13,    14, | ||||
|     15,    13,    14,    15,    13,    14,    15 ] | ||||
| 
 | ||||
| racc_action_check = [ | ||||
|     10,    10,    10,    10,    10,    10,    10,    17,    15,    10, | ||||
|     17,    17,    17,    18,    13,    17,    18,    18,    18,     4, | ||||
|     11,    18,     4,     4,     4,     1,     9,     4,     1,     1, | ||||
|      1,     8,     3,     1,     8,     8,     8,    19,    14,     8, | ||||
|     19,    19,    19,     0,   nil,    19,     0,     0,     0,    16, | ||||
|    nil,     0,    16,    16,    16,   nil,   nil,    16,     5,     5, | ||||
|      5,     5,     5,     5,     5,    30,    30,    30,    28,    28, | ||||
|     28,    29,    29,    29,    31,    31,    31 ] | ||||
| 
 | ||||
| racc_action_pointer = [ | ||||
|     37,    19,   nil,    32,    13,    55,   nil,   nil,    25,    13, | ||||
|     -3,    20,   nil,     4,    28,    -2,    43,     1,     7,    31, | ||||
|    nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,    65,    68, | ||||
|     62,    71 ] | ||||
| 
 | ||||
| racc_action_default = [ | ||||
|    -18,   -18,   -17,   -18,   -18,    -1,    -2,    -3,   -18,   -15, | ||||
|    -18,   -18,   -12,   -18,   -18,   -18,   -18,   -18,   -18,   -18, | ||||
|    -11,   -16,   -14,   -13,    32,   -10,    -8,    -9,    -4,    -5, | ||||
|     -6,    -7 ] | ||||
| 
 | ||||
| racc_goto_table = [ | ||||
|      5,    10,     3,    22,    12,   nil,   nil,   nil,    20,   nil, | ||||
|    nil,   nil,   nil,   nil,   nil,   nil,    28,    29,    30,    31 ] | ||||
| 
 | ||||
| racc_goto_check = [ | ||||
|      2,     2,     1,     5,     2,   nil,   nil,   nil,     2,   nil, | ||||
|    nil,   nil,   nil,   nil,   nil,   nil,     2,     2,     2,     2 ] | ||||
| 
 | ||||
| racc_goto_pointer = [ | ||||
|    nil,     2,     0,   nil,   nil,    -6 ] | ||||
| 
 | ||||
| racc_goto_default = [ | ||||
|    nil,   nil,   nil,     6,     7,   nil ] | ||||
| 
 | ||||
| racc_token_table = { | ||||
|  false => 0, | ||||
|  Object.new => 1, | ||||
|  :UNARY => 2, | ||||
|  "^" => 3, | ||||
|  "*" => 4, | ||||
|  "/" => 5, | ||||
|  "+" => 6, | ||||
|  "," => 7, | ||||
|  :AND => 8, | ||||
|  "-" => 9, | ||||
|  :DIGITS => 10, | ||||
|  "(" => 11, | ||||
|  ")" => 12, | ||||
|  :UNIT => 13, | ||||
|  :DURATION => 14 } | ||||
| 
 | ||||
| racc_use_result_var = true | ||||
| 
 | ||||
| racc_nt_base = 15 | ||||
| 
 | ||||
| Racc_arg = [ | ||||
|  racc_action_table, | ||||
|  racc_action_check, | ||||
|  racc_action_default, | ||||
|  racc_action_pointer, | ||||
|  racc_goto_table, | ||||
|  racc_goto_check, | ||||
|  racc_goto_default, | ||||
|  racc_goto_pointer, | ||||
|  racc_nt_base, | ||||
|  racc_reduce_table, | ||||
|  racc_token_table, | ||||
|  racc_shift_n, | ||||
|  racc_reduce_n, | ||||
|  racc_use_result_var ] | ||||
| 
 | ||||
| Racc_token_to_s_table = [ | ||||
| '$end', | ||||
| 'error', | ||||
| 'UNARY', | ||||
| '"^"', | ||||
| '"*"', | ||||
| '"/"', | ||||
| '"+"', | ||||
| '","', | ||||
| 'AND', | ||||
| '"-"', | ||||
| 'DIGITS', | ||||
| '"("', | ||||
| '")"', | ||||
| 'UNIT', | ||||
| 'DURATION', | ||||
| '$start', | ||||
| 'stmt', | ||||
| 'expr', | ||||
| 'time', | ||||
| 'iso', | ||||
| 'unit'] | ||||
| 
 | ||||
| Racc_debug_parser = false | ||||
| 
 | ||||
| ##### racc system variables end ##### | ||||
| 
 | ||||
|  # reduce 0 omitted | ||||
| 
 | ||||
|  # reduce 1 omitted | ||||
| 
 | ||||
|  # reduce 2 omitted | ||||
| 
 | ||||
|  # reduce 3 omitted | ||||
| 
 | ||||
| module_eval <<'.,.,', 'parser.ry', 18 | ||||
|   def _reduce_4( val, _values, result ) | ||||
| result += val[2] | ||||
|    result | ||||
|   end | ||||
| .,., | ||||
| 
 | ||||
| module_eval <<'.,.,', 'parser.ry', 19 | ||||
|   def _reduce_5( val, _values, result ) | ||||
| result += val[2] | ||||
|    result | ||||
|   end | ||||
| .,., | ||||
| 
 | ||||
| module_eval <<'.,.,', 'parser.ry', 20 | ||||
|   def _reduce_6( val, _values, result ) | ||||
| result += val[2] | ||||
|    result | ||||
|   end | ||||
| .,., | ||||
| 
 | ||||
| module_eval <<'.,.,', 'parser.ry', 21 | ||||
|   def _reduce_7( val, _values, result ) | ||||
| result -= val[2] | ||||
|    result | ||||
|   end | ||||
| .,., | ||||
| 
 | ||||
| module_eval <<'.,.,', 'parser.ry', 22 | ||||
|   def _reduce_8( val, _values, result ) | ||||
| result *= val[2] | ||||
|    result | ||||
|   end | ||||
| .,., | ||||
| 
 | ||||
| module_eval <<'.,.,', 'parser.ry', 23 | ||||
|   def _reduce_9( val, _values, result ) | ||||
| result /= val[2] | ||||
|    result | ||||
|   end | ||||
| .,., | ||||
| 
 | ||||
| module_eval <<'.,.,', 'parser.ry', 24 | ||||
|   def _reduce_10( val, _values, result ) | ||||
| result **= val[2] | ||||
|    result | ||||
|   end | ||||
| .,., | ||||
| 
 | ||||
| module_eval <<'.,.,', 'parser.ry', 25 | ||||
|   def _reduce_11( val, _values, result ) | ||||
| result = -val[1] | ||||
|    result | ||||
|   end | ||||
| .,., | ||||
| 
 | ||||
| module_eval <<'.,.,', 'parser.ry', 26 | ||||
|   def _reduce_12( val, _values, result ) | ||||
| result = +val[1] | ||||
|    result | ||||
|   end | ||||
| .,., | ||||
| 
 | ||||
| module_eval <<'.,.,', 'parser.ry', 27 | ||||
|   def _reduce_13( val, _values, result ) | ||||
| result =  val[1] | ||||
|    result | ||||
|   end | ||||
| .,., | ||||
| 
 | ||||
| module_eval <<'.,.,', 'parser.ry', 30 | ||||
|   def _reduce_14( val, _values, result ) | ||||
| result = val[0] * val[1] | ||||
|    result | ||||
|   end | ||||
| .,., | ||||
| 
 | ||||
| module_eval <<'.,.,', 'parser.ry', 33 | ||||
|   def _reduce_15( val, _values, result ) | ||||
| result = 1 | ||||
|    result | ||||
|   end | ||||
| .,., | ||||
| 
 | ||||
|  # reduce 16 omitted | ||||
| 
 | ||||
|  # reduce 17 omitted | ||||
| 
 | ||||
|  def _reduce_none( val, _values, result ) | ||||
|   result | ||||
|  end | ||||
| 
 | ||||
|     end   # class Parser | ||||
| 
 | ||||
|   end   # class Delta | ||||
| 
 | ||||
| end   # class Date | ||||
							
								
								
									
										84
									
								
								lib/date/delta/parser.ry
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								lib/date/delta/parser.ry
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,84 @@ | |||
| # parser.ry: Written by Tadayoshi Funaba 2006,2008,2009 -*- ruby -*- | ||||
| 
 | ||||
| class Date::Delta::Parser | ||||
| 
 | ||||
|   prechigh | ||||
|     nonassoc UNARY | ||||
|     left '^' | ||||
|     left '*' '/' | ||||
|     left '+' ',' AND '-' | ||||
|   preclow | ||||
| 
 | ||||
|   rule | ||||
| 
 | ||||
|   stmt	: expr | ||||
| 	; | ||||
| 
 | ||||
|   expr	: time | ||||
| 	| iso | ||||
| 	| expr '+' expr   {result += val[2]} | ||||
| 	| expr ',' expr   {result += val[2]} | ||||
| 	| expr AND expr   {result += val[2]} | ||||
| 	| expr '-' expr   {result -= val[2]} | ||||
| 	| expr '*' DIGITS {result *= val[2]} | ||||
| 	| expr '/' DIGITS {result /= val[2]} | ||||
| 	| expr '^' DIGITS {result **= val[2]} | ||||
| 	| '-' expr =UNARY {result = -val[1]} | ||||
| 	| '+' expr =UNARY {result = +val[1]} | ||||
| 	| '(' expr ')'    {result =  val[1]} | ||||
| 	; | ||||
| 
 | ||||
|   time	: DIGITS unit {result = val[0] * val[1]} | ||||
| 	; | ||||
| 
 | ||||
|   unit	: {result = 1} | UNIT | ||||
| 	; | ||||
| 
 | ||||
|   iso	: DURATION | ||||
| 	; | ||||
| 
 | ||||
| ---- header ---- | ||||
| ---- inner ---- | ||||
| 
 | ||||
|   def lookup(str) | ||||
|     t = str.downcase | ||||
|     k = UNITS4KEY[t] | ||||
|     return [:UNIT, k] if k | ||||
|     return [:AND, nil] if t == 'and' | ||||
|     return [:UNKNOWNWORD, nil] | ||||
|   end | ||||
| 
 | ||||
|   def parse(str) | ||||
|     @q = [] | ||||
|     until str.empty? | ||||
|       case str | ||||
|       when /\A\s+/ | ||||
|       when /\AP(\d+y)?(\d+m)?(\d+d)?t?(\d+h)?(\d+m)?(\d+s)?(\d+w)?/i | ||||
| 	y, m, d, h, min, s, w = | ||||
| 	  [$1, $2, $3, $4, $5, $6, $7].collect{|x| x.to_i} | ||||
| 	y *= UNITS4KEY['years'] | ||||
| 	m *= UNITS4KEY['months'] | ||||
| 	d *= UNITS4KEY['days'] | ||||
| 	h *= UNITS4KEY['hours'] | ||||
| 	min *= UNITS4KEY['minutes'] | ||||
| 	s *= UNITS4KEY['seconds'] | ||||
| 	w *= UNITS4KEY['weeks'] | ||||
| 	@q.push [:DURATION, y + m + d + h + min + s + w] | ||||
|       when /\A\d+/ | ||||
| 	@q.push [:DIGITS, $&.to_i] | ||||
|       when /\A[a-z]+/i | ||||
| 	@q.push lookup($&) | ||||
|       when /\A.|\n/ | ||||
| 	@q.push [$&, $&] | ||||
|       end | ||||
|       str = $' | ||||
|     end | ||||
|     @q.push [false, false] | ||||
|     do_parse | ||||
|   end | ||||
| 
 | ||||
|   def next_token | ||||
|     @q.shift | ||||
|   end | ||||
| 
 | ||||
| ---- footer ---- | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 tadf
						tadf