Parsing a string.

Discussion of Common Lisp

Parsing a string.

Postby 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?
White_Owl
 
Posts: 15
Joined: Wed Sep 13, 2017 2:49 pm

Re: Parsing a string.

Postby 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
sylwester
 
Posts: 127
Joined: Mon Jul 11, 2011 2:53 pm

Re: Parsing a string.

Postby 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)
pjstirling
 
Posts: 140
Joined: Sun Nov 28, 2010 4:21 pm

Re: Parsing a string.

Postby White_Owl » Tue Oct 24, 2017 7:21 am

Thank you...
Found two solutions:
First is smaller. Second is more flexible.
White_Owl
 
Posts: 15
Joined: Wed Sep 13, 2017 2:49 pm


Return to Common Lisp

Who is online

Users browsing this forum: No registered users and 3 guests

cron