-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathesrap.lisp
58 lines (48 loc) · 1.84 KB
/
esrap.lisp
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
(require :architecture.builder-protocol)
(require :esrap)
(cl:defpackage #:builder-protocol.example.esrap
(:use
#:cl
#:alexandria
#:architecture.builder-protocol
#:esrap)
(:shadowing-import-from #:esrap
#:?))
(cl:in-package #:builder-protocol.example.esrap)
(defrule identifier
(+ (alpha-char-p character))
(:text t))
(defrule type-reference
identifier
(:lambda (name &bounds start end)
(make+finish-node *builder* :type-reference :name name
:bounds (cons start end))))
(defrule value
(+ (digit-char-p character))
(:text t)
(:lambda (digits &bounds start end)
(make+finish-node *builder* :value :value (parse-integer digits)
:bounds (cons start end))))
(defrule variable-declaration
(and type-reference " " identifier (? (and " = " value)) (? " "))
(:destructure (type space1 name (&optional space2 value) &optional space3
&bounds start end)
(declare (ignore space1 space2 space3))
(let* ((variable (make-node *builder* :variable-declaration
:name name
:bounds (cons start end)))
(variable (relate *builder* :variable-type variable type))
(variable (if value
(relate *builder* :variable-value variable value)
variable)))
(finish-node *builder* :variable-declaration variable))))
(defrule block
(* variable-declaration)
(:lambda (declarations &bounds start end)
(finish-node
*builder* :block
(reduce (curry #'relate *builder* :block-element) declarations
:initial-value (make-node *builder* :block
:bounds (cons start end))))))
(let ((*builder* 'list))
(parse 'block "foo bar = 1 baz fez"))