Skip to content

Instantly share code, notes, and snippets.

@cbeer
Created August 4, 2011 20:03
Show Gist options
  • Save cbeer/1126095 to your computer and use it in GitHub Desktop.
Save cbeer/1126095 to your computer and use it in GitHub Desktop.
require 'rubygems'
require 'parslet'
require 'parslet/convenience'
class Duration < Parslet::Parser
rule(:integer) { match('[0-9]').repeat(1, 2) }
rule(:space) { match('\s').repeat(1) }
rule(:space?) { space.maybe }
rule(:q) { str('?') }
rule(:ca) { str('ca') >> (str('.') | str(',')).maybe }
rule(:c) { str('c') >> (str('.') | str(',')).maybe }
rule(:gt) { str('>') }
rule(:lt) { str('<') }
rule(:ish) { str('ish') }
rule(:approx) { str('approx') >> str('.').maybe }
rule(:approximate_indicator) { space? >> (gt | lt | q | ca | c| approx | ish ).as(:approximate) >> space? }
rule(:df) { str(';') }
rule(:ndf) { str(':') }
rule(:frames) { (match('[0-2]') >> match('[0-9]')).as(:frames) }
rule(:delim) { str(':') }
rule(:frame_delim) { df | ndf }
rule(:hours) { integer.as(:hours) }
rule(:minutes) { match('[0-9]').repeat(1).as(:minutes) }
rule(:seconds) { integer.as(:seconds) }
rule(:seconds_with_fraction) { (integer >> str('.') >> match('[0-9]').repeat(1)).as(:seconds) }
rule(:minutes_string) { space? >> ((match('[Mm]') >> str('in').maybe >> str('IN').maybe >> str('.').maybe >> str('ute').maybe >> str('s').maybe) | str("'")) }
rule(:minutes_with_suffix) { minutes >> minutes_string }
rule(:seconds_string) { space? >> match('[Ss]') >> str('ec').maybe >> str('.').maybe >> str('ond').maybe >> str('s').maybe }
rule(:seconds_with_suffix) { seconds >> seconds_string }
rule(:hours_string) { space? >> match('[Hh]') >> str('r').maybe >> str('rs').maybe >> str('.').maybe >> str('our').maybe >> str('s').maybe }
rule(:hours_with_suffix) { hours >> hours_string }
rule(:h_m) { hours >> delim >> minutes }
rule(:m_s) { minutes >> delim >> (seconds_with_fraction | seconds) >> minutes_string.maybe }
rule(:m) { minutes }
rule(:s) { seconds }
rule(:m_s_f) { minutes >> delim >> (seconds_with_fraction | seconds) >> frame_delim >> frames }
rule(:h_m_s) { hours >> delim >> minutes >> delim >> seconds }
rule(:h_m_s_s) { hours >> delim >> minutes >> delim >> seconds >> seconds_string }
rule(:small_h_m_s) { match('[0-3]').as(:hours) >> delim >> minutes >> delim >> seconds }
rule(:small_hh_m_s) { (str('0') >> match('[0-3]')).as(:hours) >> delim >> minutes >> delim >> seconds }
rule(:h_m_s_d) { hours >> delim >> minutes >> delim >> seconds_with_fraction }
rule(:hr_min_sec) { hours_with_suffix >> space? >> minutes_with_suffix >> space? >> seconds_with_suffix }
rule(:min_sec) { minutes_with_suffix >> space? >> seconds_with_suffix }
rule(:hrs) { hours_with_suffix }
rule(:min) { minutes_with_suffix }
rule(:sec) { seconds_with_suffix }
rule(:float_sec) { (match('[0-9]').repeat(1) >> str('.') >> match('[0-9]').repeat(1)).as(:seconds) }
rule(:smpte) { hours >> delim >> minutes >> delim >> seconds >> frame_delim >> frames }
rule(:exact) { smpte | h_m_s_d | h_m_s_s | hr_min_sec | min_sec | sec | float_sec | min | hrs | seconds_with_fraction | small_hh_m_s | small_h_m_s | m_s_f | h_m_s_s | h_m_s | m_s | h_m | m}
rule(:approximate_before) { approximate_indicator >> exact }
rule(:approximate_after) { exact >> approximate_indicator }
rule(:approximate) { approximate_before | approximate_after }
rule(:colon_prefix) { str(':') >> exact }
rule(:trt) { str('TRT') >> space? >> exact }
rule(:duration) { approximate | exact | trt | colon_prefix }
root :duration
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment