Parsing a string.

Discussion of Common Lisp
Post Reply
White_Owl
Posts: 15
Joined: Wed Sep 13, 2017 2:49 pm

Parsing a string.

Post by White_Owl » Mon Oct 23, 2017 1:56 pm

I have a file with format like

Code: Select all

text-a1 text-b1 1
text-a2 text-b2 2.98
text-a3 text-b3 3.6
Doing the reading like this:

Code: Select all

(defun myload (file-name)
  (let ((t1) (t2) (n))
    (with-open-file (in file-name :direction :input :if-does-not-exist :error)
      (loop for line = (read-line in nil) while line do (progn
        (with-input-from-string (ss line)
          (setf t1 (read ss))
          (setf t2 (read ss))
          (setf n (read ss))
          (print (concatenate 'string t1 t2)) (princ n)))))))

(myload "source.txt")
*** - CONCATENATE: TEXT-A1 is not a SEQUANCE
After some investigation, I understood that (read ss) returns a symbol, not a text.
But how to get a string from a stream?
(read) works fine for numbers, but why not for strings? What am I missing?

sylwester
Posts: 133
Joined: Mon Jul 11, 2011 2:53 pm

Re: Parsing a string.

Post by sylwester » Mon Oct 23, 2017 4:11 pm

*read* is for reading list structure and literals as in actual lisp source code. The syntax decides what type the end result will have.
*read-line* reads a line of text and returns it as a string not matter what the input looks like.
*read-char* read one character and returns it as such.

You might want to have a look at the Common Lisp Cookbook on strings for additional ideas.
I'm the author of two useless languages that uses BF as target machine.
Currently I'm planning a Scheme compiler :p

pjstirling
Posts: 166
Joined: Sun Nov 28, 2010 4:21 pm

Re: Parsing a string.

Post by pjstirling » Mon Oct 23, 2017 4:26 pm

READ is used by the common-lisp reader for reading code, so it produces results following the rules of common-lisp syntax. If your file format used (double-)quoted strings then you would get what you wanted, but if your format is fixed by something else then you will need to use a different approach.

For parsing in a way more similar to the way it would be done in other languages you can use READ-CHAR, READ-LINE, and READ-SEQUENCE, but this will leave you having to write parsing for all the weird and wacky ways of expressing numbers

The common-lisp approach to this task is to use a modified READTABLE, which lets you override the parts of common-lisp syntax that you want, while re-using whatever makes sense for your project.

It's worth observing, (as an aside), that old lisp programs did used to use symbols as strings, and by setting READTABLE-CASE to

Code: Select all

:PRESERVE
you might be able to get away with that as well (if you won't be provided with hostile data to be parsed)

White_Owl
Posts: 15
Joined: Wed Sep 13, 2017 2:49 pm

Re: Parsing a string.

Post by White_Owl » Tue Oct 24, 2017 7:21 am

Thank you...
Found two solutions: First is smaller. Second is more flexible.

Post Reply