module Fugit::Nat::Parser

Constants

INTERVALS
INTERVAL_REX
MONTHDAY_REX
NAMED_H_REX
NAMED_M_REX

prevent “mon” from eating “monday”

NHOURS
NMINUTES
OMONTHDAYS
OMONTHDAY_REX
POINTS
POINT_REX
WEEKDAYS
WEEKDAY_REX

Public Instance Methods

_and(i) click to toggle source
# File lib/fugit/nat.rb, line 109
def _and(i); rex(nil, i, /[ \t]*and[ \t]+/i); end
_and_or_or(i) click to toggle source
# File lib/fugit/nat.rb, line 110
def _and_or_or(i); rex(nil, i, /[ \t]*(and|or)[ \t]+/i); end
_and_or_or_or_comma(i) click to toggle source
# File lib/fugit/nat.rb, line 113
def _and_or_or_or_comma(i)
  rex(nil, i, /[ \t]*(,[ \t]*)?((and|or)[ \t]+|,[ \t]*)/i); end
_at(i) click to toggle source
# File lib/fugit/nat.rb, line 105
def _at(i); rex(nil, i, /[ \t]*at[ \t]+/i); end
_day_s(i) click to toggle source
# File lib/fugit/nat.rb, line 119
def _day_s(i); rex(nil, i, /[ \t]*days?[ \t]+/i); end
_dmin(i) click to toggle source
# File lib/fugit/nat.rb, line 146
def _dmin(i)
  rex(:dmin, i, /[0-5]?[0-9]/)
end
_every(i) click to toggle source

parsers bottom to top #################################################

# File lib/fugit/nat.rb, line 103
def _every(i); rex(nil, i, /[ \t]*every[ \t]+/i); end
_from(i) click to toggle source
# File lib/fugit/nat.rb, line 104
def _from(i); rex(nil, i, /[ \t]*from[ \t]+/i); end
_in_or_on(i) click to toggle source
# File lib/fugit/nat.rb, line 111
def _in_or_on(i); rex(nil, i, /(in|on)[ \t]+/i); end
_minute(i) click to toggle source
# File lib/fugit/nat.rb, line 144
def _minute(i); rex(nil, i, /[ \t]*minute[ \t]+/i) end
_on(i) click to toggle source
# File lib/fugit/nat.rb, line 106
def _on(i); rex(nil, i, /[ \t]*on[ \t]+/i); end
_point(i) click to toggle source
# File lib/fugit/nat.rb, line 235
def _point(i); rex(:point, i, POINT_REX); end
_rewrite_sub(t, key=nil) click to toggle source
# File lib/fugit/nat.rb, line 361
def _rewrite_sub(t, key=nil)
  st = t.sublookup(key)
  st ? rewrite(st) : nil
end
_rewrite_subs(t, key=nil) click to toggle source
# File lib/fugit/nat.rb, line 358
def _rewrite_subs(t, key=nil)
  t.subgather(key).collect { |ct| rewrite(ct) }
end
_sep(i) click to toggle source
# File lib/fugit/nat.rb, line 123
def _sep(i); rex(nil, i, /([ \t]+|[ \t]*,[ \t]*)/); end
_space(i) click to toggle source
# File lib/fugit/nat.rb, line 122
def _space(i); rex(nil, i, /[ \t]+/); end
_the(i) click to toggle source
# File lib/fugit/nat.rb, line 120
def _the(i); rex(nil, i, /[ \t]*the[ \t]+/i); end
_to(i) click to toggle source
# File lib/fugit/nat.rb, line 107
def _to(i); rex(nil, i, /[ \t]*to[ \t]+/i); end
_to_or_dash(i) click to toggle source
# File lib/fugit/nat.rb, line 116
def _to_or_dash(i);
  rex(nil, i, /[ \t]*-[ \t]*|[ \t]+(to|through)[ \t]+/i); end
adjust_h(h, m, ap) click to toggle source

Try to follow en.wikipedia.org/wiki/12-hour_clock#Confusion_at_noon_and_midnight

# File lib/fugit/nat.rb, line 486
def adjust_h(h, m, ap)

  if ap == 'midnight' && h == 12
    24
  elsif ap == 'pm' && h < 12 # post meridian
    h + 12
  elsif ap == 'am' && h == 12 # ante meridian
    0
  else
    h
  end
end
ampm(i) click to toggle source
# File lib/fugit/nat.rb, line 200
def ampm(i)
  rex(:ampm, i, /[ \t]*(am|pm|noon|midday|midnight)/i)
end
and_dmin(i) click to toggle source
# File lib/fugit/nat.rb, line 149
def and_dmin(i)
  seq(nil, i, :_and_or_or_or_comma, :_minute, '?', :_dmin)
end
at(i) click to toggle source
# File lib/fugit/nat.rb, line 261
def at(i)
  seq(:at, i, :_at, '?', :at_objects)
end
at_object(i) click to toggle source

at five at five pm at five o'clock at 16:30 at noon at 18:00 UTC <– …tz

# File lib/fugit/nat.rb, line 254
def at_object(i)
  alt(nil, i, :named_hour, :digital_hour, :simple_hour, :at_point)
end
at_objects(i) click to toggle source
# File lib/fugit/nat.rb, line 257
def at_objects(i)
  jseq(nil, i, :at_object, :_and_or_or_or_comma)
end
at_p(i) click to toggle source
# File lib/fugit/nat.rb, line 241
def at_p(i)
  seq(:at_p, i, :_point, :counts)
end
at_point(i) click to toggle source
# File lib/fugit/nat.rb, line 244
def at_point(i)
  jseq(nil, i, :at_p, :_and_or_or)
end
city_tz(i) click to toggle source
# File lib/fugit/nat.rb, line 184
def city_tz(i)
  rex(nil, i, /[A-Z][a-zA-Z0-9+\-]+(\/[A-Z][a-zA-Z0-9+\-_]+){0,2}/)
end
count(i) click to toggle source
# File lib/fugit/nat.rb, line 125
def count(i); rex(:count, i, /\d+/); end
counts(i) click to toggle source
# File lib/fugit/nat.rb, line 237
def counts(i)
  jseq(nil, i, :count, :_and_or_or_or_comma)
end
dark(i) click to toggle source
# File lib/fugit/nat.rb, line 203
def dark(i)
  rex(:dark, i, /[ \t]*dark/i)
end
delta_tz(i) click to toggle source
# File lib/fugit/nat.rb, line 190
def delta_tz(i)
  rex(nil, i, /[-+]([01][0-9]|2[0-4])(:?(00|15|30|45))?/)
end
digital_h(i) click to toggle source
# File lib/fugit/nat.rb, line 207
def digital_h(i)
  rex(:digital_h, i, /(2[0-4]|[0-1]?[0-9]):([0-5][0-9])/i)
end
digital_hour(i) click to toggle source
# File lib/fugit/nat.rb, line 210
def digital_hour(i)
  seq(:digital_hour, i, :digital_h, :ampm, '?')
end
every(i) click to toggle source
# File lib/fugit/nat.rb, line 340
def every(i)
  seq(:every, i, :_every, :every_objects)
end
every_interval(i) click to toggle source

every day every 1 minute

# File lib/fugit/nat.rb, line 271
def every_interval(i)
  seq(:every_interval, i, :count, '?', :interval)
end
every_named(i) click to toggle source
# File lib/fugit/nat.rb, line 326
def every_named(i)
  rex(:every_named, i, /weekday/i)
end
every_object(i) click to toggle source
# File lib/fugit/nat.rb, line 330
def every_object(i)
  alt(
    nil, i,
    :every_weekday, :every_of_the_month,
    :every_interval, :every_named, :every_single_interval)
end
every_objects(i) click to toggle source
# File lib/fugit/nat.rb, line 336
def every_objects(i)
  jseq(nil, i, :every_object, :_and_or_or)
end
every_of_the_month(i) click to toggle source

every 1st of the month every first of the month Every 2nd of the month Every second of the month every 15th of the month

# File lib/fugit/nat.rb, line 322
def every_of_the_month(i)
  seq(nil, i, :omonthdays, :otm)
end
every_single_interval(i) click to toggle source
# File lib/fugit/nat.rb, line 275
def every_single_interval(i)
  rex(:every_single_interval, i, /(1[ \t]+)?(week|year)/)
end
every_weekday(i) click to toggle source

every monday every Fri-Sun every Monday and Tuesday

# File lib/fugit/nat.rb, line 309
def every_weekday(i)
  jseq(nil, i, :weekday_range, :_and_or_or)
end
from(i) click to toggle source
# File lib/fugit/nat.rb, line 302
def from(i)
  seq(nil, i, :_from, '?', :from_objects)
end
from_object(i) click to toggle source
# File lib/fugit/nat.rb, line 296
def from_object(i)
  alt(nil, i, :to_weekday, :to_omonthday, :to_hour)
end
from_objects(i) click to toggle source
# File lib/fugit/nat.rb, line 299
def from_objects(i)
  jseq(nil, i, :from_object, :_and_or_or)
end
interval(i) click to toggle source
# File lib/fugit/nat.rb, line 265
def interval(i)
  rex(:interval, i, INTERVAL_REX)
end
monthday(i) click to toggle source
# File lib/fugit/nat.rb, line 130
def monthday(i)
  rex(:monthday, i, MONTHDAY_REX)
end
monthdays(i) click to toggle source
# File lib/fugit/nat.rb, line 138
def monthdays(i); jseq(nil, i, :monthday, :_and_or_or_or_comma); end
named_h(i) click to toggle source
# File lib/fugit/nat.rb, line 228
def named_h(i)
  rex(:named_h, i, NAMED_H_REX)
end
named_hour(i) click to toggle source
# File lib/fugit/nat.rb, line 231
def named_hour(i)
  seq(:named_hour, i, :named_h, :dark, '?', :named_min, '?', :ampm, '?')
end
named_m(i) click to toggle source
# File lib/fugit/nat.rb, line 221
def named_m(i)
  rex(:named_m, i, NAMED_M_REX)
end
named_min(i) click to toggle source
# File lib/fugit/nat.rb, line 224
def named_min(i)
  seq(nil, i, :_space, :named_m)
end
named_tz(i) click to toggle source
# File lib/fugit/nat.rb, line 187
def named_tz(i)
  rex(nil, i, /Z|UTC/)
end
nat(i) click to toggle source
# File lib/fugit/nat.rb, line 347
def nat(i)
  jseq(:nat, i, :nat_elt, :_sep)
end
nat_elt(i) click to toggle source
# File lib/fugit/nat.rb, line 344
def nat_elt(i)
  alt(nil, i, :every, :from, :at, :tzone, :on)
end
omonthday(i) click to toggle source
# File lib/fugit/nat.rb, line 127
def omonthday(i)
  rex(:omonthday, i, OMONTHDAY_REX)
end
omonthdays(i) click to toggle source
# File lib/fugit/nat.rb, line 137
def omonthdays(i); jseq(nil, i, :omonthday, :_and_or_or_or_comma); end
on(i) click to toggle source

'every month on day 2 at 10:00' => '0 10 2 * *', 'every month on day 2 and 5 at 10:00' => '0 10 2,5 * *', 'every month on days 1,15 at 10:00' => '0 10 1,15 * *',

'every week on monday 18:23' => '23 18 * * 1',

every month on the 1st
# File lib/fugit/nat.rb, line 180
def on(i)
  seq(:on, i, :_on, :on_objects)
end
on_days(i) click to toggle source
# File lib/fugit/nat.rb, line 162
def on_days(i); seq(:on_days, i, :_day_s, :monthdays); end
on_minutes(i) click to toggle source
# File lib/fugit/nat.rb, line 153
def on_minutes(i)
  seq(:on_minutes, i, :_minute, :_dmin, :and_dmin, '*')
end
on_object(i) click to toggle source
# File lib/fugit/nat.rb, line 165
def on_object(i)
  alt(nil, i, :on_days, :on_weekdays, :on_minutes, :on_thes, :on_thex)
end
on_objects(i) click to toggle source
# File lib/fugit/nat.rb, line 168
def on_objects(i)
  jseq(nil, i, :on_object, :_and)
end
on_the(i) click to toggle source
# File lib/fugit/nat.rb, line 142
def on_the(i); seq(nil, i, :_the, :omonthdays); end
on_thes(i) click to toggle source
# File lib/fugit/nat.rb, line 161
def on_thes(i); jseq(:on_thes, i, :on_the, :_and_or_or_or_comma); end
on_thex(i) click to toggle source
# File lib/fugit/nat.rb, line 157
def on_thex(i);
  rex(:on_thex, i, /[ \t]*the[ \t]+(hour|minute)[ \t]*/i);
end
on_weekdays(i) click to toggle source
# File lib/fugit/nat.rb, line 163
def on_weekdays(i); ren(:on_weekdays, i, :weekdays); end
otm(i) click to toggle source
# File lib/fugit/nat.rb, line 313
def otm(i)
  rex(nil, i, /[ \t]+of the month/)
end
rewrite_at(t) click to toggle source
# File lib/fugit/nat.rb, line 542
def rewrite_at(t)
  _rewrite_subs(t)
end
rewrite_at_p(t) click to toggle source
# File lib/fugit/nat.rb, line 405
      def rewrite_at_p(t)
        pt = t.sublookup(:point).strinpd
        pt = pt.start_with?('mon') ? 'M' : pt[0, 1]
        pts = t.subgather(:count).collect { |e| e.string.to_i }
#p [ pt, pts ]
        case pt
        #when 'm' then slot(:m, pts)
        when 'm' then slot(:hm, '*', pts, strong: 1)
        when 's' then slot(:second, pts)
        else slot(pt.to_sym, pts)
        end
      end
rewrite_digital_hour(t) click to toggle source
# File lib/fugit/nat.rb, line 499
def rewrite_digital_hour(t)

  h, m = t.sublookup(:digital_h).strinpd.split(':').collect(&:to_i)
  ap = t.sublookup(:ampm)
  h, m = adjust_h(h, m, ap && ap.strinpd), m

  slot(:hm, h, m)
end
rewrite_dmin(t) click to toggle source
# File lib/fugit/nat.rb, line 366
def rewrite_dmin(t)
  t.strinp
end
rewrite_every(t) click to toggle source
# File lib/fugit/nat.rb, line 546
def rewrite_every(t)
  _rewrite_sub(t)
end
rewrite_every_interval(t) click to toggle source
# File lib/fugit/nat.rb, line 426
      def rewrite_every_interval(t)

#Raabro.pp(t, colours: true)
        ci = t.subgather(nil).collect(&:string)
        i = ci.pop.strip[0, 3]
        c = (ci.pop || '1').strip
        i = (i == 'M' || i.downcase == 'mon') ? 'M' : i[0, 1].downcase
        cc = c == '1' ? '*' : "*/#{c}"

        case i
        when 'M' then slot(:month, cc)
        when 'd' then slot(:monthday, cc, :weak)
        #when 'h' then slot(:hm, cc, 0, weak: :minute)
        when 'h' then slot(:hm, cc, 0, weak: 1)
        when 'm' then slot(:hm, '*', cc, strong: 1)
        when 's' then slot(:second, cc)
        else {}
        end
      end
rewrite_every_named(t) click to toggle source
# File lib/fugit/nat.rb, line 446
def rewrite_every_named(t)

  case s = t.string
  when /weekday/i then slot(:weekday, '1-5', :weak)
  when /week/i then slot(:weekday, '0', :weak)
  else fail "cannot rewrite #{s.inspect}"
  end
end
rewrite_every_single_interval(t) click to toggle source
# File lib/fugit/nat.rb, line 418
def rewrite_every_single_interval(t)
  case t.string
  when /year/i then [ slot(:month, 1, :weak), slot(:monthday, 1, :weak) ]
  #when /week/i then xxx...
  else slot(:weekday, 0, :weak)
  end
end
rewrite_monthday(t) click to toggle source
# File lib/fugit/nat.rb, line 397
def rewrite_monthday(t)
  slot(:monthday, t.string.to_i)
end
rewrite_named_hour(t) click to toggle source
# File lib/fugit/nat.rb, line 516
def rewrite_named_hour(t)

  ht = t.sublookup(:named_h)
  mt = t.sublookup(:named_m)
  apt = t.sublookup(:ampm)

  h = ht.strinp
  m = mt ? mt.strinp : 0
  h = NHOURS[h]
  m = NMINUTES[m] || m

  h = adjust_h(h, m, apt && apt.strinpd)

  slot(:hm, h, m)
end
rewrite_nat(t) click to toggle source
# File lib/fugit/nat.rb, line 550
      def rewrite_nat(t)
#Raabro.pp(t, colours: true)
        Fugit::Nat::SlotGroup.new(_rewrite_subs(t).flatten)
      end
rewrite_omonthday(t) click to toggle source
# File lib/fugit/nat.rb, line 401
def rewrite_omonthday(t)
  slot(:monthday, OMONTHDAYS[t.string.downcase])
end
rewrite_on(t) click to toggle source
# File lib/fugit/nat.rb, line 393
def rewrite_on(t)
  _rewrite_subs(t)
end
rewrite_on_days(t) click to toggle source
# File lib/fugit/nat.rb, line 389
def rewrite_on_days(t)
  _rewrite_subs(t, :monthday)
end
rewrite_on_minutes(t) click to toggle source
# File lib/fugit/nat.rb, line 370
      def rewrite_on_minutes(t)
#Raabro.pp(t, colours: true)
        mins = t.subgather(:dmin).collect(&:strinp)
        #slot(:m, mins.join(','))
        slot(:hm, '*', mins.join(','), strong: 1)
      end
rewrite_on_thes(t) click to toggle source
# File lib/fugit/nat.rb, line 386
def rewrite_on_thes(t)
  _rewrite_subs(t, :omonthday)
end
rewrite_on_thex(t) click to toggle source
# File lib/fugit/nat.rb, line 377
def rewrite_on_thex(t)
  case s = t.string
  #when /hour/i then slot(:h, 0)
  #else slot(:m, '*')
  when /hour/i then slot(:hm, 0, '*', strong: 0)
  else slot(:hm, '*', '*', strong: 1)
  end
end
rewrite_on_weekdays(t)
Alias for: rewrite_weekdays
rewrite_simple_hour(t) click to toggle source
# File lib/fugit/nat.rb, line 508
def rewrite_simple_hour(t)

  h, ap = t.subgather(nil).collect(&:strinpd)
  h = adjust_h(h.to_i, 0, ap)

  slot(:hm, h, 0)
end
rewrite_to_hour(t) click to toggle source
# File lib/fugit/nat.rb, line 532
      def rewrite_to_hour(t)
#Raabro.pp(t, colours: true)
        ht0, ht1 = t.subgather(nil)
        h0, h1 = rewrite(ht0), rewrite(ht1)
        fail ArgumentError.new(
          "cannot deal with #{ht0.strinp} to #{ht1.strinp}, minutes diverge"
        ) if h0.data1 != h1.data1
        slot(:hm, "#{h0._data0}-#{h1._data0}", 0, strong: 0)
      end
rewrite_to_omonthday(t) click to toggle source
# File lib/fugit/nat.rb, line 479
def rewrite_to_omonthday(t)
  md0, md1 = _rewrite_subs(t, :omonthday).collect(&:_data0)
  slot(:monthday, "#{md0}-#{md1}")
end
rewrite_to_weekday(t) click to toggle source
# File lib/fugit/nat.rb, line 472
def rewrite_to_weekday(t)

  wd0, wd1 = _rewrite_subs(t, :weekday)
  #wd1 = 7 if wd1 == 0
  slot(:weekday, "#{wd0}-#{wd1}")
end
rewrite_tz(t) click to toggle source
# File lib/fugit/nat.rb, line 455
def rewrite_tz(t)

  slot(:tz, t.string)
end
rewrite_weekday(t) click to toggle source
# File lib/fugit/nat.rb, line 460
def rewrite_weekday(t)

  Fugit::Cron::Parser::WEEKDS.index(t.string[0, 3].downcase)
end
rewrite_weekdays(t) click to toggle source
# File lib/fugit/nat.rb, line 465
      def rewrite_weekdays(t)

#Raabro.pp(t, colours: true)
        slot(:weekday, _rewrite_subs(t, :weekday))
      end
Also aliased as: rewrite_on_weekdays
simple_h(i) click to toggle source
# File lib/fugit/nat.rb, line 214
def simple_h(i)
   rex(:simple_h, i, /#{(0..24).to_a.reverse.join('|')}/)
end
simple_hour(i) click to toggle source
# File lib/fugit/nat.rb, line 217
def simple_hour(i)
  seq(:simple_hour, i, :simple_h, :ampm, '?')
end
slot(key, data0, data1=nil, opts=nil) click to toggle source

rewrite parsed tree ###################################################

# File lib/fugit/nat.rb, line 354
def slot(key, data0, data1=nil, opts=nil)
  Slot.new(key, data0, data1, opts)
end
to_hour(i) click to toggle source
# File lib/fugit/nat.rb, line 292
def to_hour(i)
  seq(:to_hour, i, :at_object, :_to, :at_object)
end
to_omonthday(i) click to toggle source
# File lib/fugit/nat.rb, line 287
def to_omonthday(i)
  seq(:to_omonthday, i,
    :_the, '?', :omonthday, :_to, :_the, '?', :omonthday)
end
to_weekday(i) click to toggle source
# File lib/fugit/nat.rb, line 279
def to_weekday(i)
  seq(:to_weekday, i, :weekday, :_to_or_dash, :weekday)
end
tz(i) click to toggle source
# File lib/fugit/nat.rb, line 193
def tz(i)
  alt(:tz, i, :city_tz, :named_tz, :delta_tz)
end
tzone(i) click to toggle source
# File lib/fugit/nat.rb, line 196
def tzone(i)
  seq(nil, i, :_in_or_on, '?', :tz)
end
weekday(i) click to toggle source
# File lib/fugit/nat.rb, line 133
def weekday(i)
  rex(:weekday, i, WEEKDAY_REX)
end
weekday_range(i) click to toggle source
# File lib/fugit/nat.rb, line 283
def weekday_range(i)
  alt(nil, i, :to_weekday, :weekdays)
end
weekdays(i) click to toggle source
# File lib/fugit/nat.rb, line 140
def weekdays(i); jseq(:weekdays, i, :weekday, :_and_or_or_or_comma); end