Created
April 30, 2020 07:57
-
-
Save remi-dupre/7cbbc13d52e3f90006196fa8104d7250 to your computer and use it in GitHub Desktop.
grammar for OSM opening hours
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Grammar for opening hours description as defined in OSM wiki: | |
// https://wiki.openstreetmap.org/wiki/Key:opening_hours/specification | |
// Time domain | |
input_time_domain = _{ SOI ~ time_domain ~ &EOI } | |
time_domain = { rule_sequence ~ ( any_rule_separator ~ rule_sequence )* } | |
rule_sequence = { selector_sequence ~ (space ~ rules_modifier)? } | |
// Rule separators | |
any_rule_separator = { | |
normal_rule_separator | |
| additional_rule_separator | |
| fallback_rule_separator | |
} | |
normal_rule_separator = { ";" ~ space } | |
additional_rule_separator = { "," ~ space } | |
fallback_rule_separator = { space ~ "||" ~ space } | |
// Rule modifier | |
rules_modifier = { | |
rules_modifier_enum ~ ( space ~ comment )? | |
| comment | |
} | |
rules_modifier_enum = { | |
rules_modifier_enum_closed | |
| rules_modifier_enum_open | |
| rules_modifier_enum_unknown | |
} | |
rules_modifier_enum_closed = @{ "closed" | "off" } | |
rules_modifier_enum_open = @{ "open" } | |
rules_modifier_enum_unknown = @{ "unknown" } | |
// Selectors | |
selector_sequence = { | |
"24/7" | |
| wide_range_selectors ~ small_range_selectors | |
} | |
wide_range_selectors = { | |
year_selector? ~ monthday_selector? ~ week_selector? ~ | |
separator_for_readability? | |
} | |
small_range_selectors = { | |
weekday_selector ~ space ~ time_selector | |
| weekday_selector | |
| time_selector | |
} | |
separator_for_readability = { ":" } | |
// Time selector | |
time_selector = { timespan ~ ( "," ~ timespan )* } | |
timespan = { | |
time ~ "-" ~ extended_time ~ "/" ~ hour_minutes | |
| time ~ "-" ~ extended_time ~ "/" ~ minute | |
| time ~ "-" ~ extended_time ~ "+" | |
| time ~ "-" ~ extended_time | |
| time ~ "+" | |
| time | |
} | |
time = { | |
hour_minutes | |
| variable_time | |
} | |
extended_time = { | |
extended_hour_minutes | |
| variable_time | |
} | |
variable_time = { | |
"(" ~ event ~ plus_or_minus ~ hour_minutes ~ ")" | |
| event | |
} | |
event = { "dawn" | "sunrise" | "sunset" | "dusk" } | |
// Weekday selector | |
weekday_selector = { | |
holiday_sequence ~ ( "," ~ weekday_sequence )? | |
| weekday_sequence ~ ( "," ~ holiday_sequence )? | |
| holiday_sequence ~ space ~ weekday_sequence | |
} | |
weekday_sequence = { weekday_range ~ ( "," ~ weekday_range )* } | |
weekday_range = { | |
wday ~ ( nth_entry ~ ( "," ~ nth_entry )* ) ~ date_offset? | |
| wday ~ "-" ~ wday | |
| wday | |
} | |
holiday_sequence = { holiday ~ ( "," ~ holiday )* } | |
holiday = { | |
public_holiday ~ day_offset? | |
| school_holiday | |
} | |
public_holiday = { "PH" } | |
school_holiday = { "SH" } | |
nth_entry = { | |
nth ~ "-" ~ nth | |
| "-" ~ nth | |
| nth | |
} | |
nth = { '1'..'5' } | |
day_offset = { space ~ plus_or_minus ~ positive_number ~ space ~ "day" ~ "s"? } | |
// Week selector | |
week_selector = { week ~ ( "," ~ week )* } | |
week = { weeknum ~ ( "-" ~ weeknum ~ ( "/" ~ positive_number )? )? } | |
// Mounth selector | |
monthday_selector = { monthday_range ~ ( "," ~ monthday_range )* } | |
monthday_range = { | |
year? ~ month ~ ( "-" ~ month )? | |
| date_from ~ date_offset? ~ "-" ~ date_to ~ date_offset? | |
| date_from ~ date_offset* | |
} | |
date_offset = { | |
(plus_or_minus ~ wday) ~ day_offset? | |
| day_offset | |
} | |
date_from = { | |
year? ~ month ~ daynum | |
| year? ~ variable_date | |
} | |
date_to = { | |
date_from | |
| daynum | |
} | |
variable_date = { "easter" } | |
// Year selector | |
year_selector = { year_range ~ ( "," ~ year_range )* } | |
year_range = { | |
year ~ ( "-" ~ year ~ ( "/" ~ positive_number ) )? | |
| year ~ "+" | |
} | |
// Basic elements | |
plus_or_minus = @{ "+" | "-" } | |
hour = @{ | |
"00" | "01" | "02" | "03" | "04" | "05" | "06" | "07" | "08" | "09" | "10" | |
| "11" | "12" | "13" | "14" | "15" | "16" | "17" | "18" | "19" | "20" | | |
"21" | "22" | "23" | "24" | |
} | |
extended_hour = @{ | |
hour | "25" | "26" | "27" | "28" | "29" | "30" | "31" | "32" | "33" | "34" | |
| "35" | "36" | "37" | "38" | "39" | "40" | "41" | "42" | "43" | "44" | | |
"45" | "46" | "47" | "48" | |
} | |
minute = @{ | |
"00" | "01" | "02" | "03" | "04" | "05" | "06" | "07" | "08" | "09" | "10" | |
| "11" | "12" | "13" | "14" | "15" | "16" | "17" | "18" | "19" | "20" | | |
"21" | "22" | "23" | "24" | "25" | "26" | "27" | "28" | "29" | "30" | "31" | |
| "32" | "33" | "34" | "35" | "36" | "37" | "38" | "39" | "40" | "41" | | |
"42" | "43" | "44" | "45" | "46" | "47" | "48" | "49" | "50" | "51" | "52" | |
| "53" | "54" | "55" | "56" | "57" | "58" | "59" | |
} | |
hour_minutes = { hour ~ ":" ~ minute } | |
extended_hour_minutes = { extended_hour ~ ":" ~ minute } | |
wday = @{ "Su" | "Mo" | "Tu" | "We" | "Th" | "Fr" | "Sa" } | |
daynum = @{ | |
"01" | "02" | "03" | "04" | "05" | "06" | "07" | "08" | "09" | "10" | "11" | |
| "12" | "13" | "14" | "15" | "16" | "17" | "18" | "19" | "20" | "21" | | |
"22" | "23" | "24" | "25" | "26" | "27" | "28" | "29" | "30" | "31" | |
} | |
weeknum = @{ | |
"01" | "02" | "03" | "04" | "05" | "06" | "07" | "08" | "09" | "10" | "11" | |
| "12" | "13" | "14" | "15" | "16" | "17" | "18" | "19" | "20" | "21" | | |
"22" | "23" | "24" | "25" | "26" | "27" | "28" | "29" | "30" | "31" | "32" | |
| "33" | "34" | "35" | "36" | "37" | "38" | "39" | "40" | "41" | "42" | | |
"43" | "44" | "45" | "46" | "47" | "48" | "49" | "50" | "51" | "52" | "53" | |
} | |
month = @{ | |
"Jan" | "Feb" | "Mar" | "Apr" | "May" | "Jun" | "Jul" | "Aug" | "Sep" | | |
"Oct" | "Nov" | "Dec" | |
} | |
year = @{ | |
( "19" ~ ASCII_DIGIT{2} ) | |
| ( '2'..'9' ~ ASCII_DIGIT{3} ) | |
} | |
positive_number = @{ "0"* ~ ASCII_NONZERO_DIGIT ~ ASCII_DIGIT* } | |
comment = @{ comment_delimiter ~ comment_character+ ~ comment_delimiter } | |
comment_delimiter = @{ "\"" } | |
comment_character = @{ !comment_delimiter ~ ANY } | |
space = _{ " " } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment