Created
July 15, 2011 03:00
-
-
Save bluegraybox/1083966 to your computer and use it in GitHub Desktop.
This is the core functionality from https://github.com/bluegraybox/examples/blob/master/indent-parser/parse-indents.lisp
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
(defun parse-text-line (line) | |
;; converts " text" to (:content "text" :indent 4) | |
(let ((content (string-left-trim '(#\Space #\Tab) line))) | |
(list :content content :indent (- (length line) (length content))))) | |
(defun split-list (criterion data-list) | |
;; break a list into two lists; the second begins with the first element that matches the criterion. | |
(if data-list | |
(if (funcall criterion (first data-list)) | |
(list () data-list) | |
(let ((me (pop data-list))) | |
(let ((chunks (split-list criterion data-list))) | |
(push me (first chunks)) | |
chunks))) | |
(list () ()))) | |
(defun build-nodes (lines) | |
(if lines | |
(let* ((me (pop lines)) | |
;; split off our children from the rest of the lines. | |
;; the first line with an indent <= ours is a sibling, not a child | |
(chunks (split-list (lambda (x) (<= (getf x :indent) (getf me :indent))) lines))) | |
(let ((children (build-nodes (pop chunks))) | |
(siblings (build-nodes (pop chunks)))) | |
(let ((node (list :content (getf me :content)))) | |
(if children (setf (getf node :children) children)) | |
;; (format t "~a~%" (getf node :content)) | |
(push node siblings)))) | |
nil)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Here's the full code for the Lisp version of the indent parser. There's also a sequential Erlang version and a concurrent Erlang version.