blob: 0ff7806095e050442959ecb21c3ec45ebba2aa73 (
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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
|
;;; Syntax
;; an fff document translates to a key-value object containing lists or other
;; objects. Nesting objects are accomplished using references, which start with @.
;; # comments start with '#' and go to the end of the line.
;; fff-object::
;; key: value
;; key2: value2
;; key3: @reference # a reference refers to another defined object
;;
;; # lists are similar to objects, just without keys
;; fff-list::
;; : item1
;; : item2
;; : item3
;;
;; name: something # this is okay too
(import (scheme base)
(scheme case-lambda)
(utf8)
(comparse)
(srfi 14))
(define anything
(in char-set:full))
(define nl+ws
(sequence* ((_ (is #\newline))
(_ ws*))
(result " ")))
(define end
(any-of nl+ws
end-of-input))
(define end*
(any-of (one-or-more nl+ws)
end-of-input))
(define (escaped parser)
(preceded-by (is #\\) parser))
(define (unescaped parser)
(none-of* (escaped parser)
parser))
(define ws
(in char-set:blank))
(define ws*
(zero-or-more ws))
(define nonl
(in (char-set-delete char-set:full #\newline)))
(define fff-val
(sequence* ((@? (maybe (escaped (is #\@))))
(v (as-string
(zero-or-more
(any-of (escaped nl+ws)
(none-of* nl+ws item))))))
(result (if @?
(string-append "@" v)
v))))
(define fff-key
(as-string
(one-or-more
(all-of (any-of (escaped (is #\:))
(escaped nl+ws)
(none-of* (is #\:) nl+ws item))))))
(define fff-ref
(sequence* ((_ (unescaped (is #\@)))
(k fff-key))
(result (cons 'ref k))))
(define fff-comment
(sequence* ((_ (one-or-more (is #\#)))
(_ ws*)
(c (as-string (zero-or-more nonl)))
(_ end*))
(result (cons 'comment c))))
(define fff-comment+
(bind (one-or-more fff-comment)
(lambda (xs)
(result (cons 'comment (map cdr xs))))))
(define fff-item
(sequence* ((k (maybe fff-key))
(_ ws*)
(_ (is #\:))
(_ ws*)
(v (any-of fff-ref fff-val))
(_ end))
(result (cons k v))))
(define fff-item*
(sequence* ((k fff-key)
(_ ws*)
(_ (is #\:))
(_ ws*)
(v (any-of fff-ref fff-val))
(_ end*))
(result (cons k v))))
(define fff-object
(sequence* ((name fff-key)
(_ ws*)
(_ (sequence (is #\:) (is #\:) (is #\newline)))
(contents (one-or-more
(any-of fff-comment+
fff-item)))
(_ end*))
(result (cons name contents))))
(define fff-document
(zero-or-more (any-of fff-comment+
fff-object
fff-item*)))
(define (parse-fff x)
(parse fff-document x))
|