Created
April 10, 2014 09:27
-
-
Save wedesoft/10361176 to your computer and use it in GitHub Desktop.
Read CSV data with Guile (GNU Scheme)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(use-modules (system base lalr)) | |
(define csv-parse | |
(lalr-parser | |
(CELL COMMA NEWLINE RETURN) | |
(csv () : '() | |
(csv row) : (cons $2 $1)) | |
(row (nl) : (list "") | |
(COMMA row) : (cons "" $2) | |
(CELL nl) : (list $1) | |
(CELL COMMA row) : (cons $1 $3)) | |
(nl (NEWLINE) : #f | |
(RETURN NEWLINE) : #f))) | |
(define (read-string port l) | |
(let ((c (peek-char port))) | |
(if (or (char=? c #\,) (char=? c #\newline)) | |
(apply string (reverse l)) | |
(read-string port (cons (read-char port) l))))) | |
(define (read-quoted port l) | |
(let ((c (read-char port)) | |
(c2 (peek-char port))) | |
(cond ((and (char=? c #\") (char=? c2 #\")) (read-quoted port (cons (read-char port) l))) | |
((char=? c #\") (apply string (reverse l))) | |
(else (read-quoted port (cons c l)))))) | |
(define (lex port err) | |
(lambda () | |
(let* ((line (port-line port)) | |
(col (port-column port)) | |
(loc (make-source-location port line col -1 -1)) | |
(c (read-char port))) | |
(cond ((eof-object? c) '*eoi*) | |
((char=? c #\newline) (make-lexical-token 'NEWLINE loc #f)) | |
((char=? c #\return) (make-lexical-token 'RETURN loc #f)) | |
((char=? c #\,) (make-lexical-token 'COMMA loc #f)) | |
((char=? c #\") (make-lexical-token 'CELL loc (read-quoted port '()))) | |
(else (make-lexical-token 'CELL loc (read-string port (list c)))))))) | |
(define (err msg . args) (display msg)) | |
(write (call-with-input-string "a,b\n\"c\",d\n,f\ng,\n\"h\"\"i\"\"\",j\n\"\",k\nlm,\"\"\n" | |
(lambda (port) (reverse (csv-parse (lex port err) err))))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment