[comp.lang.lisp] Building a string, character-by-character

dkb@cs.brown.edu (Dilip Barman) (10/01/90)

I'm writing a lexical analyzer in Common LISP and am having problems
in dealing with characters.  I am using the read-char built-in 
function to read from a file stream in a "standard" way to ignore
white space and fold to upper case alphabetic characters.  However,
I find no way to deal with string concatenation - i.e., how do I 
keep tacking on filtered characters to a nascent output string?
The cons primitive will build a list structure and seems to be
irrelevant to what I'm trying to do.  Any suggestions????

Dilip Barman     dkb@cs.brown.edu
U.S. mail: Brown University                       Home: 40 Everett Avenue
           Dept. of Computer Science, Box 1910          Providence, RI 02906
           Providence, RI 02912 (401)863-7666           (401)521-9731

michaelg@Neon.Stanford.EDU (Michael Greenwald) (10/01/90)

dkb@cs.brown.edu (Dilip Barman) writes:


>I'm writing a lexical analyzer in Common LISP and am having problems
>in dealing with characters.  I am using the read-char built-in 
>function to read from a file stream in a "standard" way to ignore
>white space and fold to upper case alphabetic characters.  However,
>I find no way to deal with string concatenation - i.e., how do I 
>keep tacking on filtered characters to a nascent output string?
>The cons primitive will build a list structure and seems to be
>irrelevant to what I'm trying to do.  Any suggestions????

Would VECTOR-PUSH or VECTOR-PUSH-EXTEND be what you are looking for?

>Dilip Barman     dkb@cs.brown.edu
>U.S. mail: Brown University                       Home: 40 Everett Avenue
>           Dept. of Computer Science, Box 1910          Providence, RI 02906
>           Providence, RI 02912 (401)863-7666           (401)521-9731

sra@ecs.soton.ac.uk (Stephen Adams) (10/02/90)

In article <51703@brunix.UUCP> dkb@cs.brown.edu (Dilip Barman) writes:

 > 
 > I'm writing a lexical analyzer in Common LISP and am having problems
 > in dealing with characters.  I am using the read-char built-in 
 > function to read from a file stream in a "standard" way to ignore
 > white space and fold to upper case alphabetic characters.  However,
 > I find no way to deal with string concatenation - i.e., how do I 
 > keep tacking on filtered characters to a nascent output string?
 > The cons primitive will build a list structure and seems to be
 > irrelevant to what I'm trying to do.  Any suggestions????

I had this problem.

You can use CONCATENATE to do the job but I found that it
was awfully slow:

	(setf word (concatenate 'string word (string input-char)))



The fastest solution I found was to keep a large string
lying around (in a global variable or better, a closure) and
put the characters into this string.

When the item of input is complete copy the string.  This
saves all the allocation required by the list or concatenate
approach.  Off the top of my head, I used something like
this.  It is horrible lisp style.  With a good compiler it
goes fast if you tell it that I is a fixnum and BUF is a
simple string.


	(defvar buf (make-string 1000))
	(defvar ch)
	(defmacro readch () `(setf ch (read-char *input-file* nil)))

	(defun read-identifier (&aux (i 0))
	   ;; called when CH is a letter
	   (setf ch (char-upcase ch))
	   (loop
	     (setf (char buf i) ch) (incf i)
             (readch)
             (if (and ch (alphanumericp ch))	;AND checks it is not NIL
		 (setf ch (char-upcase ch))
		 (return (subseq buf 0 i)))))

--
Stephen Adams                        S.R.Adams@ecs.soton.ac.uk
Computer Science                     S.R.Adams@sot-ecs.uucp
Southampton University
Southampton SO9 5NH, UK