Implement faster key/value parser.

This commit is contained in:
Dominik Pantůček 2023-05-16 22:00:54 +02:00
parent debeb2fd59
commit 2514e93ce3

View file

@ -35,7 +35,6 @@
(import scheme (import scheme
(chicken base) (chicken base)
(chicken irregex)
testing) testing)
;; Pass 0: Removes any comments and removes any leading and trailing ;; Pass 0: Removes any comments and removes any leading and trailing
@ -69,17 +68,29 @@
;; one token was there and pair of symbol and string if both key and ;; one token was there and pair of symbol and string if both key and
;; the value were present. ;; the value were present.
(define (parser-parse-line line) (define (parser-parse-line line)
(if (= (string-length line) 0) (let* ((llen (string-length line))
#f (spos (let sloop ((sidx 0))
(let ((dm (irregex-search (irregex "[ \\t]" 'u) line))) (if (or (= sidx llen)
(if dm (let ((ch (string-ref line sidx)))
(let* ((sep-idx (irregex-match-start-index dm)) (or (eq? ch #\space)
(key-str (substring line 0 sep-idx)) (eq? ch #\tab))))
(key (string->symbol key-str)) sidx
(sep+val (substring line sep-idx)) (sloop (add1 sidx)))))
(val (irregex-replace (irregex "^[ \\t]*" 'u) sep+val ""))) (vpos (let vloop ((vidx spos))
(cons key val)) (if (or (= vidx llen)
(string->symbol line))))) (not (let ((ch (string-ref line vidx)))
(or (eq? ch #\space)
(eq? ch #\tab)))))
vidx
(vloop (add1 vidx))))))
(if (= llen 0)
#f
(if (< vpos llen)
(cons (string->symbol
(substring line 0 spos))
(substring line vpos))
(string->symbol
(substring line 0 spos))))))
;; Self-tests ;; Self-tests
(define (parser-tests!) (define (parser-tests!)