1
0
Fork 0
mirror of synced 2024-05-17 11:03:33 +12:00

.glyphs format parser

This commit is contained in:
Nikita Prokopov 2018-09-28 01:00:09 +03:00
parent 5db65a50b4
commit b273e21463
3 changed files with 108 additions and 0 deletions

2
.gitignore vendored
View file

@ -1,3 +1,5 @@
*.zip
FiraCode_liga.glyphs
FiraCode_mess.glyphs
target
clojure/FiraCode.edn

99
clojure/parse_glyphs.clj Executable file
View file

@ -0,0 +1,99 @@
(ns parse-glyphs
(:require
[clojure.java.io :as io]
[fipp.edn :as fipp]))
(def ^:dynamic *str)
(def ^:dynamic *pos)
(defn current-char [] (nth @*str @*pos))
(defn advance! [] (swap! *pos inc))
(declare parse-anything!)
(defn skip-ws! []
(loop []
(case (current-char)
\space (do (advance!) (recur))
\newline (do (advance!) (recur))
nil)))
(defn parse-escaped-string! []
(skip-ws!)
(when (= \" (current-char))
(let [sb (StringBuilder.)]
(loop []
(advance!)
(let [ch (current-char)]
(cond
(= ch \\) (do (.append sb \\) (advance!) (.append sb (current-char)) (recur))
(= ch \") (do (advance!) (str sb))
:else (do (.append sb ch) (recur))))))))
(defn parse-string! []
(skip-ws!)
(let [sb (StringBuilder.)]
(loop []
(let [ch (current-char)]
(cond
(#{\space \newline \{ \} \( \) \; \, \" \=} ch) sb
:else (do (.append sb ch) (advance!) (recur)))))
(let [res (str sb)]
(cond
(re-matches #"[0-9]+" res) (Integer/parseInt res)
(re-matches #"[0-9]+\.[0-9]+" res) (Double/parseDouble res)
(re-matches #"[a-zA-Z][a-zA-Z\.0-9]*" res) (keyword res)
:else res))))
(defn expect [c]
(assert (= c (current-char)) (str "Expected '" c "', found " (current-char) " at " @*pos)))
(defn parse-map! []
(skip-ws!)
(when (= \{ (current-char))
(advance!)
(loop [m {}]
(skip-ws!)
(if (= \} (current-char))
(do (advance!) m)
(let [k (or (parse-escaped-string!) (parse-string!))
_ (do (skip-ws!) (expect \=) (advance!))
v (parse-anything!)
v (if (keyword? v) (name v) v)
_ (do (skip-ws!) (expect \;) (advance!))]
(recur (assoc m k v)))))))
(defn parse-list! []
(skip-ws!)
(when (= \( (current-char))
(advance!)
(loop [l []]
(skip-ws!)
(if (= \) (current-char))
(do (advance!) l)
(let [v (parse-anything!)
_ (skip-ws!)
_ (when (not= \) (current-char))
(expect \,)
(advance!))]
(recur (conj l v)))))))
(defn parse-anything! []
(skip-ws!)
(or
(parse-map!)
(parse-list!)
(parse-escaped-string!)
(parse-string!)))
(defn parse [s]
(binding [*str (atom s)
*pos (atom 0)]
(parse-anything!)))
(defn -main [& args]
(let [f (-> (slurp "FiraCode.glyphs") parse)]
(with-open [os (io/writer "clojure/FiraCode.edn")]
(binding [*out* os]
(fipp/pprint f {:width 200})))))

7
project.clj Normal file
View file

@ -0,0 +1,7 @@
(defproject org.example/sample "1.0.0-SNAPSHOT"
:dependencies [
[org.clojure/clojure "1.10.0-alpha8"]
[fipp "0.6.12"]
]
:source-paths ["clojure"]
)