grammar ScheduleCronParser

rule user_crontab
  sep?
  (environment sep)?
  jobspecs?
  sep?
end

rule environment
  directive (sep directive)*
end

rule directive
  var space "=" space expr
end

rule var
  alpha alphanumeric?
end

rule expr
  command
end

rule jobspecs
  jobspec (sep jobspec)*
end

rule jobspec
  schedule_spec space command ws*
end

rule schedule_spec
  standard | special
end

rule standard
  minute space hour space dayofmonth space month space dayofweek
end

rule special
  "@" ("yearly" | "annually" | "monthly" | "weekly" | "daily" | "hourly" | "reboot")
end

rule minute
  step
end

rule hour
  step
end

rule dayofmonthtypes
  step
end

rule monthtypes
  step | altmonths
end

rule dayofweektypes
  step | altdays
end

rule dayofmonth
  dayofmonthtypes ("," dayofmonthtypes)*
end

rule month
  monthtypes ("," monthtypes)*
end

rule dayofweek
  dayofweektypes ("," dayofweektypes)*
end

rule command
  quoted_string
  | (!("\n" | comment) .)+
end

rule step
  common ("/" int)?
end

rule common
  range | int | any
end

rule range
  int "-" int
end

rule altdays
  days ("," days)*
end

rule altmonths
  months ("," months)*
end

rule days
  "MON" | "TUE" | "WED" | "THU" | "FRI" | "SAT" | "SUN"
end

rule months
  "JAN" | "FEB" | "MAR" | "APR" | "MAY" | "JUN" | "JUL" | "AUG" | "SEP" | "OCT" | "NOV" | "DEC"
end

rule any
  "*"
end

rule int
  [0-9]+
end

rule alpha
  [a-zA-Z]+
end

rule alphanumeric
  [a-zA-Z0-9]+
end

rule sep
  (ws* nl)+
end

rule ws
  space | comment
end

rule space
  [ \t]+
end

rule nl
  [\n]+
end

rule comment
  "#" (!"\n" .)*
end

rule quoted_string
  "\"" ( (!("\"" | "\\") .) | escape)*  "\""
  | "'" ( (!("'" | "\\") .) | escape)*  "'"
end

rule escape
  "\\" escape_sequence
end

rule escape_sequence
  "'"
  | "\""
  | "\\"
  | "b"
  | "f"
  | "n"
  | "r"
  | "t"
  | "v"
end

end