-
Notifications
You must be signed in to change notification settings - Fork 3
/
parse-rules.lisp
23 lines (22 loc) · 1.63 KB
/
parse-rules.lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
(in-package :pq)
(defrule value () form)
(defrule unit-factor-unit () (not (or '-> '/ 'per '|per| 'square '|square| 'cubic '|cubic| '^ '** 'to 'the '+/- '+-)))
(defrule unit-factor-fmt-a () (and (or '|square| 'square '|cubic| 'cubic) unit-factor-unit)
(:destructure (power unit) (list unit (case power (square 2) (|square| 2) (cubic 3) (|cubic| 3)))))
(defrule unit-factor-fmt-b () (and unit-factor-unit (or '|squared| 'squared '|cubed| 'cubed))
(:destructure (unit power) (list unit (case power (squared 2) (|squared| 2) (cubed 3) (|cubed| 3)))))
(defrule unit-factor-fmt-c () (and unit-factor-unit (? (and (or '^ '** (and 'to 'the) (and '|to| '|the|)) form)))
(:destructure (unit power) (list unit (second power))))
(defrule unit-factor () (and (? (or '/ 'per '|per|)) (or unit-factor-fmt-a unit-factor-fmt-b unit-factor-fmt-c))
(:destructure (per (unit power)) `(make-uf ,(if (stringp unit) unit (symbol-name unit)) ,(if power (if per `(- ,power) power) (if per -1 1)))))
(defrule error () (and (or '+/- '+-) value (? '%))
(:destructure (pm val percent) (declare (ignore pm)) (if percent `(- (/ ,val 100)) val)))
(defrule errval () (and value (? error))
(:destructure (val err) (list val (if err err 0))))
(defrule conversion () (and '-> (+ unit-factor))
(:destructure (arrow unit-factors) (declare (ignore arrow)) unit-factors))
(defrule unit () (* unit-factor))
;; form [{+/-|+-} form [%]] {[{/|per}] symbol [{^|**|to the} form]}* [-> {[{/|per}] symbol [{^|**|to the} form]}+]
(defrule quantity () (and errval unit (? conversion)))
(defrule unit-definition () (and form unit)
(:destructure (conv unit-factors) `(,conv (list ,@unit-factors))))