about summary refs log tree commit diff stats
path: root/fff.parse.ss
diff options
context:
space:
mode:
Diffstat (limited to 'fff.parse.ss')
-rw-r--r--fff.parse.ss125
1 files changed, 125 insertions, 0 deletions
diff --git a/fff.parse.ss b/fff.parse.ss new file mode 100644 index 0000000..0ff7806 --- /dev/null +++ b/fff.parse.ss
@@ -0,0 +1,125 @@
1;;; Syntax
2;; an fff document translates to a key-value object containing lists or other
3;; objects. Nesting objects are accomplished using references, which start with @.
4
5;; # comments start with '#' and go to the end of the line.
6;; fff-object::
7;; key: value
8;; key2: value2
9;; key3: @reference # a reference refers to another defined object
10;;
11;; # lists are similar to objects, just without keys
12;; fff-list::
13;; : item1
14;; : item2
15;; : item3
16;;
17;; name: something # this is okay too
18
19(import (scheme base)
20 (scheme case-lambda)
21 (utf8)
22 (comparse)
23 (srfi 14))
24
25(define anything
26 (in char-set:full))
27
28(define nl+ws
29 (sequence* ((_ (is #\newline))
30 (_ ws*))
31 (result " ")))
32
33(define end
34 (any-of nl+ws
35 end-of-input))
36
37(define end*
38 (any-of (one-or-more nl+ws)
39 end-of-input))
40
41(define (escaped parser)
42 (preceded-by (is #\\) parser))
43
44(define (unescaped parser)
45 (none-of* (escaped parser)
46 parser))
47
48(define ws
49 (in char-set:blank))
50
51(define ws*
52 (zero-or-more ws))
53
54(define nonl
55 (in (char-set-delete char-set:full #\newline)))
56
57(define fff-val
58 (sequence* ((@? (maybe (escaped (is #\@))))
59 (v (as-string
60 (zero-or-more
61 (any-of (escaped nl+ws)
62 (none-of* nl+ws item))))))
63 (result (if @?
64 (string-append "@" v)
65 v))))
66
67(define fff-key
68 (as-string
69 (one-or-more
70 (all-of (any-of (escaped (is #\:))
71 (escaped nl+ws)
72 (none-of* (is #\:) nl+ws item))))))
73
74(define fff-ref
75 (sequence* ((_ (unescaped (is #\@)))
76 (k fff-key))
77 (result (cons 'ref k))))
78
79(define fff-comment
80 (sequence* ((_ (one-or-more (is #\#)))
81 (_ ws*)
82 (c (as-string (zero-or-more nonl)))
83 (_ end*))
84 (result (cons 'comment c))))
85
86(define fff-comment+
87 (bind (one-or-more fff-comment)
88 (lambda (xs)
89 (result (cons 'comment (map cdr xs))))))
90
91(define fff-item
92 (sequence* ((k (maybe fff-key))
93 (_ ws*)
94 (_ (is #\:))
95 (_ ws*)
96 (v (any-of fff-ref fff-val))
97 (_ end))
98 (result (cons k v))))
99
100(define fff-item*
101 (sequence* ((k fff-key)
102 (_ ws*)
103 (_ (is #\:))
104 (_ ws*)
105 (v (any-of fff-ref fff-val))
106 (_ end*))
107 (result (cons k v))))
108
109(define fff-object
110 (sequence* ((name fff-key)
111 (_ ws*)
112 (_ (sequence (is #\:) (is #\:) (is #\newline)))
113 (contents (one-or-more
114 (any-of fff-comment+
115 fff-item)))
116 (_ end*))
117 (result (cons name contents))))
118
119(define fff-document
120 (zero-or-more (any-of fff-comment+
121 fff-object
122 fff-item*)))
123
124(define (parse-fff x)
125 (parse fff-document x))