(defun parse (input) (nyala:parse (input) (document -> (++ :sep value) (? :sep) => `(document ,@$1)) (value -> (or :number :symbol array object string)) (array -> "[" (* :sep) (? (++ :sep value) (? :sep)) "]" => `(array ,@(second $3))) (object -> "{" (* :sep) (? (++ :sep value-pair) (? :sep)) "}" => `(object ,@(alexandria:mappend #'identity (second $3)))) (value-pair -> value :sep value => `(,$1 ,$3)) (string -> verbatim-string) (verbatim-string -> :line => `(verb ,$1)) (:line -> '"|" (= it (- (* t) #\Newline)) :eol => it) (:number -> (? #\-) (or #\0 "[1-9][0-9]*") (? "\\.[0-9]+") (? "[Ee][+-]?[0-9]+") => (let ((*read-default-float-format* 'double-float)) (read-from-string $$))) (:symbol -> "[A-Za-z+_][A-Za-z0-9-]+" => (intern $$)) (:sep -> (+ (or #\Space #\Tab #\: #\, #\Return #\Newline))) (-> (or #\Space #\Tab #\: #\, #\Return #\Newline)))) (parse "-1234.32e1 hello 1234 [ what bobby ] { hoho there 1234 444 } [ ] { } | hi there | what is []") ;; => (DOCUMENT -12343.2d0 |hello| 1234 (ARRAY |what| |bobby|) (OBJECT |hoho| |there| 1234 444) (ARRAY) (OBJECT) (VERB " hi there | what is") (ARRAY))