3

I hope these codes

(12 3.5 1e4)

could be treated as three symbols

(|12| |3.5| |1e4|)

rather than three numbers.

Can I fulfill this by setting the reader?


Update:

I have a collection of data which is organized as nested lists:

(abc,d/e-f    12ab, 21e4, %rqa, (foo bar), ....)

Different items are separated by commas or spaces (tab and newline included). I want to read them in w.r.t. the nested structure, and without changing any character. The commas can be set as spaces by this:

(set-syntax-from-char #\, #\Space)

Finally the problem remains at the numbers. 21e4 is transferred to 210000.0 by the reader. I don't want to write a parser all from scratch, and try to utilize the reader of common-lisp as much as possible.

SaltyEgg
  • 1,498
  • 1
  • 15
  • 26

2 Answers2

4

Example for 1, works in LispWorks:

CL-USER 1 > (setf rt0 *readtable*)
#<READTABLE 40F0038923>

CL-USER 2 > (setf rt1 (copy-readtable nil))
#<READTABLE 4020008C23>

CL-USER 3 > (defun read-digit-symbol (stream char)
              (let ((*readtable* rt0))
                (unread-char char stream)
                (intern
                  (princ-to-string
                    (read stream t nil t)))))
READ-DIGIT-SYMBOL

CL-USER 4 > (set-macro-character #\1 #'read-digit-symbol t rt1)
T

CL-USER 5 > (defun test ()
              (let ((*readtable* rt1))
                (read-from-string "(1 11 111)")))
TEST

CL-USER 6 > (test)
(\1 |11| |111|)
10

CL-USER 7 > 
Rainer Joswig
  • 136,269
  • 10
  • 221
  • 346
  • 2
    I like it if he can specify that his data doesn't contain ratios, e.g. 111/111 -> |1| in my local sbcl. I would additionally be tempted to bind \*read-base\* and \*print-base\* at some point to ensure that they are in sync during the read and the princ. Even if he binds them to 2 in TEST he will need to set the reader macro for all 10 digits, or else floats will still read as numbers. – m-n Jan 11 '14 at 19:32
  • 1
    Thanks for your answer first, but this is not exactly what I want. For example, if the text is `123.000`, the `(intern (princ-to-string ...` will turn it to `|123.0|`, which is not equal to `|123.000|`. In your solution, the texts are first converted to numbers and then converted back to symbol, during this procedure the content may change. – SaltyEgg Jan 12 '14 at 02:34
  • @SaltyEgg: you may want to edit your question to describe the requirements in more detail... – Rainer Joswig Jan 12 '14 at 04:50
  • @RainerJoswig Sorry for my non-detailed question. I've updated it. – SaltyEgg Jan 12 '14 at 05:57
3

You could, I guess. But that would probably end in tears, as you would lose the ability to read numbers.

What are you trying to accomplish, with this, that isn't solvable by iterating over a list of numbers, creating symbols with make-symbol and string?

Vatine
  • 20,782
  • 4
  • 54
  • 70
  • 3
    This is a good response, but should be a comment rather than an answer. – lurker Jan 11 '14 at 17:34
  • 1
    I just have to process a collection of symbols, and some of them are legal numbers for common lisp. I don't want CL to convert them to numbers. – SaltyEgg Jan 12 '14 at 02:25