-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathabnf-consumers.scm
120 lines (102 loc) · 3.69 KB
/
abnf-consumers.scm
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
;;
;; Convenience procedures and macros for manipulating items in the
;; stream of consumed tokens returned by an abnf-based parser.
;;
;; Copyright 2009-2018 Ivan Raikov
;;
;; This program is free software: you can redistribute it and/or
;; modify it under the terms of the GNU General Public License as
;; published by the Free Software Foundation, either version 3 of
;; the License, or (at your option) any later version.
;;
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
;; General Public License for more details.
;;
;; A full copy of the GPL license can be found at
;; <http://www.gnu.org/licenses/>.
(module abnf-consumers
*
(import scheme (chicken base) srfi-1
abnf utf8 utf8-srfi-14)
;; collects all consumed objects of type obj?
(define (consumed-objects obj?)
(lambda (cs)
(and (or (pair? cs) (null? cs))
(let loop ((cs cs) (ax (list)))
(cond ((null? cs) (list ax))
((obj? (car cs))
(loop (cdr cs) (cons (car cs) ax)))
(else (cons ax cs)))))))
;; construct composite objects from consumed objects
(define (consumed-objects-lift get-consumed)
(lambda rest
(let-optionals rest ((kons identity))
(let ((make (if (procedure? kons) kons (lambda (x) (and (list? x) `(,kons . ,x))))))
(lambda (x)
(let ((x1 (get-consumed x)))
(and x1 (pair? x1) (list? (car x1))
(let ((item (make (car x1))))
(if item
(cons item (cdr x1))
(cdr x1))
))
))
))
))
(define consumed-chars (consumed-objects char?))
(define consumed-chars->list (consumed-objects-lift consumed-chars))
(define (trim-ws-char-list cs)
(let* ((cs1 (let loop ((cs cs))
(cond ((null? cs) (reverse cs))
((char-set-contains? char-set:whitespace (car cs))
(loop (cdr cs)))
(else (reverse cs)))))
(cs2 (let loop ((cs cs1))
(cond ((null? cs) (reverse cs))
((char-set-contains? char-set:whitespace (car cs))
(loop (cdr cs)))
(else (reverse cs))))))
cs2))
;; construct strings from consumed chars
(define consumed-chars->string
(consumed-chars->list list->string))
;; construct symbols from consumed chars; trailing and preceding white
;; space is stripped
(define consumed-chars->symbol
(consumed-chars->list
(compose string->symbol list->string trim-ws-char-list)))
(define consumed-strings (consumed-objects string?))
(define consumed-strings->list (consumed-objects-lift consumed-strings))
(define consumed-pairs (consumed-objects pair?))
(define consumed-pairs->list (consumed-objects-lift consumed-pairs))
;; shortcut for (bind (consumed-chars->list) ... )
(define-syntax bind-consumed->list
(syntax-rules ()
((_ p) (bind (consumed-chars->list) p))
((_ l p) (bind (consumed-chars->list l) p))
))
;; shortcut for (bind consumed-chars->string ... )
(define-syntax bind-consumed->string
(syntax-rules ()
((_ p) (bind consumed-chars->string p))
))
;; shortcut for (bind consumed-chars->symbol ... )
(define-syntax bind-consumed->symbol
(syntax-rules ()
((_ p) (bind consumed-chars->symbol p))
))
;; shortcut for (bind (consumed-strings->list ...) ... )
(define-syntax bind-consumed-strings->list
(syntax-rules ()
((_ l p) (bind (consumed-strings->list l) p))
((_ p) (bind (consumed-strings->list) p))
))
;; shortcut for (bind (consumed-pairs->list ...) ... )
(define-syntax bind-consumed-pairs->list
(syntax-rules ()
((_ l p) (bind (consumed-pairs->list l) p))
((_ p) (bind (consumed-pairs->list) p))
))
)