blob: 5f570d5e9c3ef3796432b1487cfd896912b3f27c (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
|
(in-package #:json)
(defparameter number-parser
(let ((signed-digits
(comp ((sign (zero-or-one (unit (lambda (x) (or (char= x #\-)
(char= x #\+))))))
(natural (one-or-more (unit #'digit-char-p))))
(cons sign natural))))
(comp ((base (either signed-digits
(fail "Malformed number.")))
(dot (zero-or-one (unit (lambda (x) (char= x #\.)))))
(fraction (if dot
(either (one-or-more (unit #'digit-char-p))
(fail "Malformed fractional part."))
nothing))
(e (zero-or-one (unit (lambda (x) (or (char= x #\e)
(char= x #\E))))))
(exponent (if e
(either signed-digits
(fail "Malformed exponent part."))
nothing)))
(list 'number base fraction exponent))))
(defparameter string-parser
(comp ((start (unit (lambda (x) (char= x #\"))))
(chars (zero-or-more (either (comp ((slash (unit (lambda (x) (char= x #\\))))
(escaped (unit))
(codepoints (if (and escaped (char= escaped #\u))
(comp ((cp0 (unit #'digit-char-p))
(cp1 (unit #'digit-char-p))
(cp2 (unit #'digit-char-p))
(cp3 (unit #'digit-char-p)))
(let ((str (make-string 4)))
(setf (char str 0) cp0)
(setf (char str 1) cp1)
(setf (char str 2) cp2)
(setf (char str 3) cp3)
str))
nothing)))
(case escaped
(#\n
#\Newline)
(#\t
#\Tab)
(#\u
codepoints)
(t escaped)))
(unit (lambda (x) (char/= x #\"))))))
(end (unit (lambda (x) (char= x #\")))))
(list 'string chars)))
|