Changeset trunk,5 for trunk/parse2.lisp
- Timestamp:
- 06/08/2007 03:19:22 AM (19 years ago)
- revision id:
- svn-v3-trunk0:2948df59-2b31-0410-8e06-c40c0b09d5b6:trunk:5
- File:
-
- 1 edited
-
trunk/parse2.lisp (modified) (10 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/parse2.lisp
r4 r5 4 4 (import '(parse::with-gensyms parse::substring)) 5 5 6 (defvar *follow* t)6 (defvar *follow* nil) 7 7 8 8 (defmacro follow (fmt &rest args) 9 9 (when *follow* 10 10 `(format t ,fmt ,@args))) 11 12 (defun whole (n) 13 (declare ((or null (integer 0)) n)) 14 (when (and n (/= n 0)) n)) 15 16 (defun min- (n) 17 (declare ((or null (integer 1)) n)) 18 (when (and n (> n 1)) (1- n))) 19 20 (defun max- (n) 21 (declare ((or null (integer 0)) n)) 22 (when n (1- n))) 11 23 12 24 (defmacro with-character-parser ((name char) &body body) … … 20 32 (when (and (> (length ,input) 0) (char= (char ,input 0) ,char)) 21 33 (values t (substring ,input :start 1) '(,char))))) 34 (declare (inline ,name)) 22 35 ,@body))) 36 37 (defmacro with-string-parser ((name string) &body body) 38 (declare (symbol name) 39 (string string)) 40 (follow "with-string-parser~%") 41 (let ((len (length string))) 42 (with-gensyms (input) 43 `(flet ((,name (,input) 44 ,(format nil "String parser for ~S." string) 45 (declare (string ,input)) 46 (when (and (>= (length ,input) ,len) 47 (string= ,input ,string :end1 ,len)) 48 (values t (substring ,input :start ,len) '(,string))))) 49 (declare (inline ,name)) 50 ,@body)))) 51 52 (defmacro with-regex-parser ((name regex) &body body) 53 (error "Not implemented.")) 23 54 24 55 (defmacro with-sequence-parser% ((name seq) &body body) … … 36 67 (,head ,input) 37 68 (when ,matched (,tail ,left (append ,tree ,found)))))) 69 (declare (inline ,name)) 38 70 ,@body))) 39 71 `(flet ((,name (,input ,tree) … … 41 73 (declare (list ,tree)) 42 74 (values t ,input ,tree))) 75 (declare (inline ,name)) 43 76 ,@body)))) 44 77 … … 54 87 (,subname ,input nil) 55 88 (when ,matched (values t ,left (list ,found)))))) 89 (declare (inline ,name)) 56 90 ,@body)))) 57 91 … … 71 105 (values t ,left ,found) 72 106 (,tail ,input))))) 107 (declare (inline ,name)) 73 108 ,@body))) 74 109 `(flet ((,name (,input) 75 110 "Choice parser for base case." 76 111 (declare (ignore ,input)))) 112 (declare (inline ,name)) 77 113 ,@body)))) 78 114 … … 85 121 ,(format nil "Required parser for ~S." rule) 86 122 (when (,sub ,input) (values t ,input nil)))) 123 (declare (inline ,name)) 87 124 ,@body)))) 88 125 … … 95 132 ,(format nil "Forbidden parser for ~S." rule) 96 133 (unless (,sub ,input) (values t ,input nil)))) 134 (declare (inline ,name)) 97 135 ,@body)))) 98 136 … … 110 148 ,(format nil "Range parser {~S, ~S} for ~S." 111 149 mincount maxcount rule) 112 (cond 113 ((and ,min (> ,min 0)) 114 (multiple-value-bind (,matched ,left ,found) (,sub ,input) 115 (when ,matched 116 (,subname (1- ,min) (when ,max (1- ,max)) 117 ,left (append ,tree ,found))))) 118 ((and ,max (> ,max 0)) 119 (multiple-value-bind (,matched ,left ,found) (,sub ,input) 120 (if ,matched 121 (,subname nil (1- ,max) 122 ,left (append ,tree ,found)) 123 (values t ,input ,tree)))) 124 ((and ,max (= ,max 0)) (values t ,input ,tree)) 125 (t (multiple-value-bind (,matched ,left ,found) 126 (,sub ,input) 127 (if ,matched 128 (,subname nil nil ,left (append ,tree ,found)) 129 (values t ,input ,tree))))))) 130 (flet ((,name (,input) (,subname ,mincount ,maxcount ,input nil))) 150 151 (if (and ,max (= ,max 0)) 152 153 ;; Only time this can happen (because we can't 154 ;; create a {*,0} parser) is after already 155 ;; collecting some matches. Because MAX >= MIN 156 ;; always, we've also already collected *enough*. 157 (values t ,input ,tree) 158 159 ;; We haven't hit the limit (if any), so try 160 ;; another match. 161 (multiple-value-bind (,matched ,left ,found) (,sub ,input) 162 (cond 163 (,matched (,subname (min- ,min) (max- ,max) 164 ,left (append ,tree ,found))) 165 ;; Either no minimum, or already filled it 166 ;; (by the saturating MIN-), so succeed. 167 ((not ,min) (values t ,input ,tree)) 168 169 ;; Return NIL 170 ))))) 171 172 (flet ((,name (,input) 173 (,subname ,(whole mincount) ,(whole maxcount) ,input nil))) 174 (declare (inline ,name)) 131 175 ,@body))))) 132 176 … … 135 179 (follow "with-parser~%") 136 180 (etypecase rule 137 (character 138 `(with-character-parser (,name ,rule) ,@body))181 (character `(with-character-parser (,name ,rule) ,@body)) 182 (string `(with-string-parser (,name ,rule) ,@body)) 139 183 (list 140 184 (destructuring-bind (head . tail) rule 141 185 (case head 186 (^ (destructuring-bind (regex) tail 187 `(with-regex-parser (,name ,regex) ,@body))) 142 188 (/ `(with-choice-parser (,name ,tail) ,@body)) 143 189 (& (destructuring-bind (subrule) tail
Note: See TracChangeset
for help on using the changeset viewer.
