Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
310 views
in Technique[技术] by (71.8m points)

parsing - Racket Lisp - using 'read' with trying to parse the whole input string

I use the function read in Racket for parsing arbitrary input strings. For example,

 >(read (open-input-string "(1 (b 1))")) ; ==> returns '(1 (b 1))

In this example above the parentheses are matching - the problem is with input strings, where the parentheses are unmatched/unbalanced, like

 > (read (open-input-string "(+ 1 1)(")) ; ==> returns '(+ 1 1)

In this case read ignores the last parentheses '(' in the input string - I would like read to try parse the whole input string or when not possible, because of unmatched parentheses, to throw an exception. Thank you.

question from:https://stackoverflow.com/questions/65641202/racket-lisp-using-read-with-trying-to-parse-the-whole-input-string

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The read procedure only reads a single datum from the input port; the extra parenth does not raise an error in your code because it is never reached. One solution is to write a procedure that reads from the input port until the end is reached, collecting the resulting forms in a list:

(define (read-from-string s)
  (let ((input (open-input-string s)))
    (let loop ((expr (read input))
               (result '()))
      (if (eof-object? expr)
          (reverse result)
          (loop (read input) (cons expr result))))))

If read can successfully parse all of the expressions, a list of those expressions will be returned; otherwise an error will be signaled.

Sample interactions:

scratch.rkt> (read-from-string "(1 (b 1))")
'((1 (b 1)))
scratch.rkt> (read-from-string "(+ 1 2)")
'((+ 1 2))
scratch.rkt> (read-from-string "(+ 1 2) (+ 3 4)")
'((+ 1 2) (+ 3 4))
scratch.rkt> (read-from-string "()")
'(())
scratch.rkt> (read-from-string "(+ 1 1))")
; string::8: read: unexpected `)`
scratch.rkt> (read-from-string "(+ 1 1)(")
; string::8: read: expected a `)` to close `(`

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...