Clojure Instaparse examples
;; "human" date/time format parsing | |
(def human-time-parser | |
(insta/parser | |
"S = H (':' M)? ' '? P? (' ' Z)? | |
H = #'[1-9]' | #'1[0-2]' | |
M = #'0[0-9]' | #'[1-5][0-9]' | |
P = AM | PM | |
AM = 'A' 'M'? | |
PM = 'P' 'M'? | |
Z = 'EST' | 'ET' | 'CST' | 'CT' | 'PST' | 'PT' | 'MST' | 'MT'" | |
:string-ci true)) | |
(defn interpret-parse [tree] | |
(reduce (fn [acc elem] | |
(if (vector? elem) | |
(let [[tag & vals] elem] | |
(case tag | |
:H (assoc acc :hour (Integer/parseInt (first vals))) | |
:M (assoc acc :minute (Integer/parseInt (first vals))) | |
:P (assoc acc :period (ffirst vals)) | |
:Z (assoc acc :timezone (first vals)) | |
acc)) | |
acc)) | |
{} | |
tree)) | |
(defn parse->date-time [date {:keys [hour minute period timezone] | |
:or {minute 0 period :PM}}] | |
(let [hour (case period ;; convert 12- to 24-hour time | |
:AM (if (= 12 hour) 0 hour) | |
:PM (if (< 0 hour 11) | |
(+ 12 hour) | |
hour)) | |
tz (condp #(cs/starts-with? %2 %1) (or timezone "CST") | |
"C" (time/time-zone-for-id "US/Central") | |
"E" (time/time-zone-for-id "US/Eastern") | |
"P" (time/time-zone-for-id "US/Pacific") | |
"M" (time/time-zone-for-id "US/Mountain"))] | |
(-> (time/with-time-at-start-of-day date) | |
(.withHourOfDay hour) | |
(.withMinuteOfHour minute) | |
(time/from-time-zone tz)))) | |
(def test-inputs | |
["10:01 am est" | |
"12 am" | |
"12 P CST" | |
"1am" | |
"2p PT" | |
"11:11p" | |
"1:00"]) | |
(sequence | |
(comp | |
(map human-time-parser) | |
(map interpret-parse) | |
(map #(parse->date-time (time/now) %))) | |
test-inputs) | |
;; bowling scores | |
(def bowling-score-parser | |
(insta/parser | |
"S = F F F F F F F F F 10TH | |
F = OPEN | CLOSED | |
OPEN = ROLL ROLL | |
CLOSED = STRIKE | SPARE | |
10TH = OPEN | | |
SPARE (STRIKE | ROLL) | | |
STRIKE (SPARE | ROLL ROLL) | | |
STRIKE STRIKE (STRIKE | ROLL) | |
STRIKE = 'X' | |
SPARE = ROLL '/' | |
ROLL = PINS | MISS | |
PINS = #'[1-9]' | |
MISS = '-'")) | |
(bowling-score-parser "XXXXX6/XX7/XX5") | |
(bowling-score-parser "XXXXXXXXXXXX") | |
(bowling-score-parser "XXXXXXXXXX-/") | |
(bowling-score-parser "XXXXXXXXX--") | |
(bowling-score-parser "9-9-9-9-9-9-9-9-9-9-") | |
(bowling-score-parser "X7/9-X-88/-6XXX81") | |
(bowling-score-parser "X7/9-X-88/-6XX-/X") | |
(bowling-score-parser "X-/X5-8/9-X811-4/X") | |
(bowling-score-parser "6271X9-8/XX3572-/X") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment