[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: read-from-string



In article <Pine.3.89.9505171119.A541074839-0100000@medcolpa.edu> balls@medcolpa.edu writes:

   In an attempt to read a list of items from a flat file database
   so that I may create objects for storage in WOOD, I need to read
   items from a string of the general form:

   "item1; item2; item3;
   item4."

   to yield -> (item1 item2 item3 item4)

   The period "." allegedly always defines the end.

   I wrote the following:

   (let ((str "item1; item2; item3;
   item4.")
	 (i 0)
	 (result nil))
     (loop
       (multiple-value-bind 
	 (s j)
	 (read-from-string str nil 'done :start i)
	 (cond ((eq s 'done) (return (reverse result)))
	       ((string/= (string-right-trim '(#\.) s) s)

Your doing a string trim and a string comparison just to see if S ends in a
#\. right?  How about (char= (char s (- (length s) 1)) #\.)

		(push (intern (string-upcase
			       (string-right-trim '(#\.) s)))
		      result)
		(return (reverse result)))
	       (t
		(push s result)
		(setf i (+ j 1)))))))

   but in the recent discussions of read-from-string, big hammers
   & so forth, is their an obviously more efficient way of
   accomplishing this? The file I am reading is 77 MB is size.

If these things are that simple, modify your read table so that #\; is
treated as white space and #\. returns a token.  Alternatively you could
READ an item and then peek-char at the next character to see if it is a #\;
or a #\.  

If speed is very important, write your own lexical analyzer.  I'll send you
the code i'm using now.

k
--
Ken Anderson 
Internet: kanderson@bbn.com
BBN ST               Work Phone: 617-873-3160
10 Moulton St.       Home Phone: 617-643-0157
Mail Stop 6/4a              FAX: 617-873-2794
Cambridge MA 02138
USA