Created
October 28, 2014 22:55
-
-
Save sordina/6bcb30d9e2690e6e1f08 to your computer and use it in GitHub Desktop.
Simple parser to convert a string into a tree representing the structure of indented lines.
This file contains hidden or 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
(ns instap) | |
(defn text [l] (clojure.string/replace l #"^\s+" "")) | |
(assert (= (text " \t\t\t asdf") "asdf")) | |
(defn value [c] | |
(condp = c | |
\space 1 | |
\tab 4 | |
0 )) | |
(assert (= (value \space) 1)) | |
(assert (= (value \tab ) 4)) | |
(assert (= (value \x ) 0)) | |
(defn indented [l] | |
(->> l | |
(re-find #"^\s+") | |
(map value) | |
(apply +))) | |
(assert (= (indented " hello") 3)) | |
(assert (= (indented "\t\thello") 8)) | |
(defn node [x xs] [x xs]) | |
(assert (= (node 1 2) [1 2])) | |
(defn less-than [[ai _] [bi _]] (< ai bi)) | |
(defn until-less-than [l ls] (split-with (partial less-than l) ls)) | |
(assert (= (less-than [4 :x] [5 :y]) true)) | |
(assert (= (less-than [6 :x] [5 :y]) false)) | |
(assert (= (until-less-than [1 :a] [[2 :b] [1 :c] [:q :r]]) [[[2 :b]] [[1 :c] [:q :r]]])) | |
(defn line [[i l]] l) | |
(declare buildForest) | |
(defn null [] []) | |
(defn singleton [[l]] [ (node (line l) []) ]) | |
(defn complex [[l & ls]] (let [[gt lt] (split-with (partial less-than l) ls)] | |
(cons (node (line l) (buildForest gt)) (buildForest lt)))) | |
(defn buildForest [ls] | |
(condp = (count ls) | |
0 (null) | |
1 (singleton ls) | |
(complex ls))) | |
(assert (= (buildForest [[0 "a b c"]]) [["a b c" []]])) | |
(defn makeLine [l] [(indented l), (text l)]) | |
(assert (= (makeLine " asdf") [4 "asdf"])) | |
(defn lines [l] (re-seq #"[^\n]+" l)) | |
(assert (= (lines "asdf\nqwer") ["asdf" "qwer"])) | |
(defn notBlank [l] (re-find #"\S" l)) | |
(assert (notBlank "foo")) | |
(defn parse [s] (->> s | |
lines | |
(filter notBlank) | |
(map makeLine) | |
buildForest | |
)) | |
(assert (= (parse "abc\n def") [["abc" [["def" []]]]])) | |
; (parse "a b c\n d e f\n g h i") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment