[Top][All Lists]

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

Re: [Chicken-users] unterminated string error

From: Felix
Subject: Re: [Chicken-users] unterminated string error
Date: Wed, 04 Sep 2002 09:28:02 +0200
User-agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.0.0) Gecko/20020530

Peter Keller wrote:

I was getting an unterminated string error in my code and the error was
pretty bad in telling me where it happened. So I decided to fix it....

It turned out to be a lot harder than I thought because so much stuff
(like newlines, etc) can be inside a string.


(define str "this
a big
(valid string).")

The trouble is, what happens if you do this:

(define str "this
a big
(valid string).)

(display (+ 2 3))
(display "\n")

You get an "Error: unterminated string" message. :) I tried to fix up
this message by telling me the possible real start of the unterminated
string, but I couldn't do it because basically EVERYTHING is allowed in
a string until the next " is read all by itself. This means the second "
in the last display line was being marked as the start of the unterminated
string since technically, it is. In other languages that usually forbid
newlines in literal string constants, you can do this pretty easily. But
how would you do it here? Having to spend a long time debugging an
unterminated string error in a huge body of code is mind numbing.

Hm. I have no real answer for this, I'm afraid. One could perhaps
optionally disallow multi-line strings... No - that's bad.

Also, in library.scm: the r-string function, why isn't #\" also taken care
of in the #\\ case when reading a string? This would leave me to believe
that in certain situations you cannot read "\"these\"" kinds of strings.

         (define (r-string)
            (if (eq? (read-char port) #\")
                (let loop ((c (read-char port)) (lst '()))
                  (cond ((##core#inline "C_eofp" c)
                         (##sys#read-error "unterminated string") )
                        ((eq? #\\ c)
                         (set! c (read-char port))
                         (case c
                           ((#\t) (set! c #\tab))
                           ((#\r) (set! c #\return))
                           ((#\b) (set! c #\backspace))
                           ((#\n) (set! c #\newline)) )

                        ; Here the case falls through, c == '\"' and
                        ; it's handled as the general case: any char
                        ; that is escaped and not special (as the one
                        ; above) is simply put directly into the string.

                         (loop (read-char port) (cons c lst)) )
                        ((eq? #\" c) (list->string (reverse lst)))
                        ((eq? c #\newline)
                         (loop (read-char port) (cons c lst)) )
                        (else (loop (read-char port) (cons c lst))) ) )
                (##sys#read-error "missing '\"'") ) )

(A typical example of my usual convoluted coding style ;-)


reply via email to

[Prev in Thread] Current Thread [Next in Thread]