read-delimited-list
read-delimited-list Function
Syntax:
read-delimited-list char &optional input-stream recursive-p → list
Arguments and Values:
char—a character .
input-stream—an input stream designator . The default is standard input.
recursive-p—a generalized boolean. The default is false.
list—a list of the objects read.
read-delimited-listDescription:
read-delimited-list reads objects from input-stream until the next character after an object’s representation (ignoring whitespace2 characters and comments) is char.
read-delimited-list looks ahead at each step for the next non-whitespace2 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.
If recursive-p is true, this call is expected to be embedded in a higher-level call to read or a similar function.
It is an error to reach end-of-file during the operation of read-delimited-list.
The consequences are undefined if char has a syntax type of whitespace2 in the current readtable.
Examples:
(read-delimited-list #\]) 1 2 3 4 5 6 ]
→ (1 2 3 4 5 6)
Suppose you wanted #\{*a b c . . . z*\} to read as a list of all pairs of the elements *a*, *b*, *c*, *. . .*, *z*, for example.
#\{p q z a\} reads as ((p q) (p z) (p a) (q z) (q a) (z a))
This can be done by specifying a macro-character definition for #\{ that does two things: reads in all the items up to the \}, and constructs the pairs. **read-delimited-list** performs the first task.
(defun |#\{-reader| (stream char arg)
(declare (ignore char arg))
(mapcon #’(lambda (x)
(mapcar #’(lambda (y) (list (car x) y)) (cdr x)))
(read-delimited-list #\\} stream t))) → |#\{-reader|
(set-dispatch-macro-character #\# #\\{ #’|#\{-reader|) → T
(set-macro-character #\\} (get-macro-character #\) **nil**))
Note that *true* is supplied for the *recursive-p* argument.
It is necessary here to give a definition to the character \} as well to prevent it from being a constituent. If the line
(set-macro-character #\\} (get-macro-character #\) **nil**))
shown above were not included, then the \} in
#\{ p q z a\}
would be considered a constituent character, part of the symbol named a\}. This could be corrected by putting a space before the \}, but it is better to call **set-macro-character**.
Giving \} the same definition as the standard definition of the character ) has the twin benefit of making it terminate tokens for use with **read-delimited-list** and also making it invalid for use in any other context. Attempting to read a stray \} will signal an error.
Affected By:
*standard-input*, *readtable*, *terminal-io*.
See Also:
read, peek-char, read-char, unread-char.
Notes:
read-delimited-list is intended for use in implementing reader macros. Usually it is desirable for char to be a terminating macro character so that it can be used to delimit tokens; however, read-delimited-list makes no attempt to alter the syntax specified for char by the current readtable. The caller must make any necessary changes to the readtable syntax explicitly.
Expanded Reference: read-delimited-list
TODO: Please contribute to this page by adding explanations and examples
(read-delimited-list )