Skip to content

Instantly share code, notes, and snippets.

@kpuputti
Created December 5, 2015 21:33
Show Gist options
  • Save kpuputti/2c6b44d490bb49336534 to your computer and use it in GitHub Desktop.
Save kpuputti/2c6b44d490bb49336534 to your computer and use it in GitHub Desktop.
AWS string parser.
(ns aws-parser.core
(:require [clojure.string :as str]))
(defn whitespace? [c]
(str/blank? (str c)))
;; STATES: :default :whitespace :quoted
(defn- handle-char [{:keys [state result]} c]
(cond
;; :default -> :whitespace
(and (= state :default) (whitespace? c))
{:state :whitespace :result (conj result \space)}
;; :default -> :quoted
(and (= state :default) (= c \"))
{:state :quoted :result (conj result c)}
;; :default -> :default
(= state :default)
{:state :default :result (conj result c)}
;; :whitespace -> :whitespace
(and (= state :whitespace) (whitespace? c))
{:state :whitespace :result result}
;; :whitespace -> :quoted
(and (= state :whitespace) (= c \"))
{:state :quoted :result (conj result c)}
;; :whitespace -> :default
(= state :whitespace)
{:state :default :result (conj result c)}
;; :quoted -> :default
(and (= state :quoted) (= c \"))
{:state :default :result (conj result c)}
;; :quoted -> :quoted
(= state :quoted)
{:state :quoted :result (conj result c)}))
(defn parse [s]
(let [characters (seq (str/trim s))
initial {:state :default
:result []}
parsed (reduce handle-char initial characters)]
(-> parsed :result str/join)))
;; ================ TESTS ================ ;;
(def tests [["" ""]
["foobar" "foobar"]
[" foo bar " "foo bar"]
["\t\n\n - foo bar baz" "- foo bar baz"]
["\"foo bar\"" "\"foo bar\""]
[" foo \"bar baz \" yarr " "foo \"bar baz \" yarr"]])
(defn run-tests []
(doseq [[in expected] tests]
(let [result (parse in)]
(assert (= result expected)
(str "When parsing \""
in
"\" expected \""
expected
"\" but got \""
result
"\""))))
(println "ok"))
(comment
(run-tests)
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment