removing piped dot in string common lisp

480 views Asked by At

my task is to parse that list

(100 30 5 . 50 6)

to number 135.56

format of input list is always the same

and I've wrote:

(reduce 
    'string-concat 
    (mapcar 
        (lambda (x) (remove #\0 x)) 
        (mapcar 
            'write-to-string
            l
        )
    )
)

and output I've "135|.|56" and then read-from-string does'n read it, so...

have You any idea how I can do this parsing?

using or not code above

2

There are 2 answers

0
Rainer Joswig On BEST ANSWER

Your approach does not look particular robust. Also it is kind of difficult to understand what the input list is. Is the dot a symbol, like in |.|? The vertical bars are escaping the name, so that it does not collide with the built-in usage of the dot character in Lisp. It is used in dotted pairs, which stand for cons cells: (a . b).

If it is a symbol, then you can write the symbol without escaping to a string. First, with escaping:

CL-USER 5 > (write-to-string '|.|)
"\\."

Next, without:

CL-USER 6 > (princ-to-string '|.|)
"."
0
Frank Zalkow On

Your list (100 30 5 . 50 6) isn't a valid list structure in Common Lisp. A "dotted pair" must have only one element after the dot. If you want to know more about it, look at your favorite Common Lisp Book how lists are build from cons cells. (For example Peter Seibels "Practical Common Lisp")

So you cannot parse this string as a list as such - you need to have a pre-processing step.

(defun pre-processing (str)
  (let ((idx (position #\. str)))
    (list (read-from-string (concatenate 'string (subseq str 0 idx) ")"))
          (read-from-string (concatenate 'string "(" (subseq str (1+ idx)))))))

This function splits your string in two lists that you can process the way you want to.

CL-USER 1 > (pre-processing "(100 30 5 . 50 6)")
((100 30 5) (50 6))