-
Notifications
You must be signed in to change notification settings - Fork 0
/
herp-core.rkt
56 lines (46 loc) · 1.47 KB
/
herp-core.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
#lang racket
; Herp Core implements the minimal core
; of a context-free language recognizer.
(require "memoization.rkt")
(require "fixed-points.rkt")
(require "lazy-structs.rkt")
(provide (all-defined-out))
; Atomic languages:
(define-struct ∅ {}) ; empty set
(define-struct ε {}) ; empty string
(define-struct token {value}) ; exact terminal
; Compound languages:
(define-lazy-struct δ {lang}) ; nullability
(define-lazy-struct ∪ {this that}) ; union
(define-lazy-struct ∘ {left right}) ; concatenation
(define-lazy-struct ★ {lang}) ; repetition
; Derivative:
(define/memoize (D c L)
#:order ([L #:eq] [c #:equal])
(match L
[(∅) (∅)]
[(ε) (∅)]
[(δ _) (∅)]
[(token a) (cond [(eqv? a c) (ε)]
[else (∅)])]
[(∪ L1 L2) (∪ (D c L1)
(D c L2))]
[(★ L1) (∘ (D c L1) L)]
[(∘ L1 L2) (∪ (∘ (δ L1) (D c L2))
(∘ (D c L1) L2))]))
; Nullability:
(define/fix (nullable? L)
#:bottom #f
(match L
[(∅) #f]
[(ε) #t]
[(token _) #f]
[(★ _) #t]
[(δ L1) (nullable? L1)]
[(∪ L1 L2) (or (nullable? L1) (nullable? L2))]
[(∘ L1 L2) (and (nullable? L1) (nullable? L2))]))
; Parse a list of tokens:
(define (recognizes? w L)
(if (null? w)
(nullable? L)
(recognizes? (cdr w) (D (car w) L))))