I am familiar with the basic template for collecting the Lisp objects from a file, as in:
(with-open-file (stream "filename.lisp")
(loop for object = (read stream nil 'eof)
until (eq object 'eof)
collect object))
But I'm not sure how to translate this into collecting the objects from a string, for example using read-from-string. Do you then have to keep track of the index where you left off in the string? Also, how do you avoid a name conflict with eof or any other legitimate Lisp object like nil or t in the input?