Parsing Lisp in <50 LOC

Submitted by 365degrees in lisp (edited )

Alright, code is data and other cool crap, but you only get strings as input and you need S-expressions. No big deal, here's a parser I made for practise. Consider it licensed under the public domain cause it's incredibly simple and there's roughly one way to parse Lisp. (JS-based syntax highlighting breaks on #\Characters.)

(defun read-list (stream)
  (if (char= (peek-char t stream) #\))
        (read-char stream) 
      (cons (read-sexp stream)
            (read-list stream))))

(defun read-atom (stream &optional (collected nil))
  (let ((char (peek-char (null collected) stream nil :eof)))
      ((eql char :eof)
         (coerce (nreverse collected) 'string))))
      ((member char
               '(#\Space #\Newline #\Tab #\( #\))
               :test #'char=)
         (coerce (nreverse collected) 'string))))
       (read-atom stream
                  (cons (read-char stream)

(defun read-string (stream &optional (collected nil))
  (let ((char (read-char stream)))
    (if (char= char #\")
        (coerce (nreverse collected) 'string)
        (read-string stream
                     (cons char collected)))))

(defun read-sexp (stream)
  (let ((char (read-char stream)))
    (case char
       (read-list stream))
       (read-string stream (list char)))
       (read-atom stream (list char))))))
(defun read-from-string* (string)
  (with-input-from-string (stream string)
(read-sexp stream)))

I've tried everything I can think of to break it, but it seems rigid enough.


You must log in or register to comment.