-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathreader.rkt
78 lines (64 loc) · 2.49 KB
/
reader.rkt
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
#lang racket
(require "tokenizer.rkt"
"parser.rkt"
"grammar-simplifier.rkt"
"grammar-lower.rkt")
(define (read-syntax path port)
(define parse-tree (parse path (make-tokenizer port)))
(define module-datum `(module amb-parser-mod amb-parser/expander
,(lower-grammar (simplify-grammar (syntax->datum parse-tree)))))
(datum->syntax #f module-datum))
(provide (contract-out
[read-syntax (any/c input-port? . -> . syntax?)]))
(module+ test
(require rackunit
brag/support)
(define (parse-str str)
(syntax->datum (parse "" (make-tokenizer (open-input-string str)))))
(define (parse-fail str)
(lambda ()
(parse "" (make-tokenizer (open-input-string str)))))
(define-syntax-rule (check-parse? got should)
(check-equal? (parse-str got)
(cons 'parser-syntax should)))
(define-syntax-rule (check-parse-fail str)
(check-exn exn:fail:parsing? (parse-fail str)))
(check-parse? "S : NP VP;"
'((rule "S" ":"
(alteration
(expansion (non-terminal "NP")
(non-terminal "VP")))
";")))
(check-parse? "S : NP VP; NP : det noun;"
'((rule "S" ":"
(alteration
(expansion (non-terminal "NP")
(non-terminal "VP")))
";")
(rule "NP" ":"
(alteration
(expansion (terminal "det")
(terminal "noun")))
";")))
(check-parse? "A : a? B;"
'((rule "A" ":"
(alteration
(expansion (terminal "a" "?")
(non-terminal "B")))
";")))
(check-parse? "A : a* B;"
'((rule "A" ":"
(alteration
(expansion (terminal "a" "*")
(non-terminal "B")))
";")))
(check-parse? "A : a*? B;"
'((rule "A" ":"
(alteration
(expansion (terminal "a" "*" "?")
(non-terminal "B")))
";")))
(check-parse-fail "a : b c;")
(check-parse-fail "A b c;")
(check-parse-fail "A : b c")
(check-parse-fail "A : b?* c;"))