Pascal J. Bourguignon
8/8/2015 11:16:00 AM
"Pascal J. Bourguignon" <pjb@informatimago.com> writes:
> Taoufik Dachraoui <dachraoui.taoufik@gmail.com> writes:
>
>> But how i did it seems to work with dotted lists
>
> Because you are using an implementation that doesn't have a conforming
> read-delimited-list function.
>
> $ clall -r '(ignore-errors (with-input-from-string (in "a . b)") (read-delimited-list #\) in)))'
>
> Armed Bear Common Lisp --> NIL, #<READER-ERROR {287C20AB}>
> Clozure Common Lisp --> (A . B)
> CLISP --> NIL, #<SYSTEM::SIMPLE-READER-ERROR #x000334C26C30>
> CMU Common Lisp --> NIL, #<READER-ERROR {581A622D}>
> ECL --> NIL, #<a SI::SIMPLE-READER-ERROR>
> SBCL --> NIL, #<SB-INT:SIMPLE-READER-ERROR "dot context error" {1003A22A93}>
>
>
> read-delimited-list is specified in no uncertain terms:
>
>
> read-delimited-list looks ahead at each step for the next
> non-whitespace[2] character and peeks at it as if with peek-char. If
> it is char, then the character is consumed and the list of objects
> is returned. If it is a constituent or escape character, then read
> is used to read an object, which is added to the end of the list. If
> it is a macro character, its reader macro function is called; if the
> function returns a value, that value is added to the list. The
> peek-ahead process is then repeated.
>
>
> Therefore here is a conforming implementation of read-delimited-list, on
> the standard character set (for a "correct" extension to unicode, one
> would need to include a table of all the unicode whitespace characters).
>
> Notice that we don't enter into the detail of constituent and escape, we
> assume that any non-whitespace and non macro-character is a
> consitituent or an escape character.
>
> Notice also that there's is simply no way to determine the syntax type
> of a character! It's possible to change the syntax type of characters
> using SET-SYNTAX-FROM-CHAR, so the current readtable could contain only
> whitespaces or only escape characters, or it could exchange the role of
> whitespaces and constituent characters, which makes it impossible in
> general to even probe it. Therefore we just assume here that the set of
> whitespace is the standard specified default set.
>
> A real implementation would have access to the current syntax type of
> the characters.
>
>
>
> (shadow 'read-delimited-list)
>
> (defun whitespacep (ch)
> (find ch #(#\space #\tab #\newline #\linefeed #\page #\return)))
>
> (defun constituent-or-escape-p (ch)
> (and (not (get-macro-character ch))
> ;; order important.
> (not (whitespacep ch)))
>
> (defun read-delimited-list (ch &optional (stream *standard-input*)
> recursivep)
> (let ((result '()))
> (loop
> (let ((next (peek-char nil stream)))
> (cond ((char= next ch)
(read-char stream) ; then the character is consummed!
> (return (nreverse result)))
> ((let ((mc (get-macro-character next)))
> (when mc
> (let ((objects (multiple-value-list (funcall mc stream (read-char stream)))))
> (when objects
> (push (first objects) result)))
> t)))
> ((constituent-or-escape-p next)
> (push (read stream t nil recursivep) result))
> (t ; whitespace
> (read-char stream)))))))
>
> (with-input-from-string (in "a b d)")
> (read-delimited-list #\) in))
> (a b d)
>
> (with-input-from-string (in "a '(a b c) #(1 2 3) b d)")
> (read-delimited-list #\) in))
> (a '(a b c) #(1 2 3) b d)
>
> (princ (nth-value 1 (ignore-errors
> (with-input-from-string (in "a b . d)")
> (read-delimited-list #\) in)))))
> Reader error on #<string-input-stream :closed #x30200232C20D>:
> Dot context error in ".".#<ccl::simple-reader-error #x302002328C4D>
--
__Pascal Bourguignon__