Changeset trunk,2
- Timestamp:
- 06/01/2007 02:43:59 PM (19 years ago)
- revision id:
- svn-v3-trunk0:2948df59-2b31-0410-8e06-c40c0b09d5b6:trunk:2
- Location:
- trunk
- Files:
-
- 1 added
- 1 edited
-
parse.asd (added)
-
parse.lisp (modified) (8 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/parse.lisp
r1 r2 1 (defpackage #:parse 2 (:use #:cl #:cl-ppcre) 3 (:export #:defgrammar 4 #:token)) 5 6 (in-package #:parse) 7 8 9 10 1 11 (defstruct token 2 12 class … … 59 69 ,@body)) 60 70 71 (defun substring (string &key (start 0) end length) 72 (when (and end length) (error "Specify only one of END or LENGTH.")) 73 (when end (setf length (- end start))) 74 (unless length (setf length (- (length string) start))) 75 (make-array length 76 :element-type 'character 77 :displaced-to string 78 :displaced-index-offset start)) 79 80 (defmacro scase (sym &body clauses) 81 (with-gensyms (sym-name) 82 `(let ((,sym-name (symbol-name ,sym))) 83 (cond 84 ,@(mapcar #'(lambda (clause) 85 (if (eq t (first clause)) 86 clause 87 (let ((clause-sym-name (symbol-name (first clause))) 88 (clause-body (rest clause))) 89 `((string= ,sym-name ,clause-sym-name) 90 ,@clause-body)))) 91 clauses))))) 92 93 94 61 95 62 96 … … 98 132 (when matched 99 133 (parse-eqcount (1- count) rule-parser rlist (append tree mtree)))) 134 (values t token-list tree))) 135 136 (defun parse-mincount (count rule-parser token-list tree) 137 (if (> count 0) 138 (multiple-value-bind (matched rlist mtree) 139 (funcall rule-parser token-list) 140 (when matched 141 (parse-mincount (1- count) rule-parser rlist (append tree mtree)))) 142 (parse-anycount rule-parser token-list tree))) 143 144 (defun parse-maxcount (count rule-parser token-list tree) 145 (if (> count 0) 146 (multiple-value-bind (matched rlist mtree) 147 (funcall rule-parser token-list) 148 (if matched 149 (parse-maxcount (1- count) rule-parser rlist (append tree mtree)) 150 (values t token-list tree))) 100 151 (values t token-list tree))) 101 152 … … 112 163 (values t (rest ,token-list) (list ,token)))))))) 113 164 165 (defun make-character-parser (ch) 166 (with-gensyms (str) 167 `(lambda (,str) 168 (when (and (> (length ,str) 0) (char= (char ,str 0) ,ch)) 169 (values 170 t 171 (substring ,str :start 1) 172 (list ,ch)))))) 173 174 (defun make-regex-parser (regex) 175 (let ((regex `(:sequence (:flags :single-line-mode-p) :start-anchor 176 (:register (:regex ,regex))))) 177 (with-gensyms (str start end) 178 `(lambda (,str) 179 (multiple-value-bind (,start ,end) (scan (quote ,regex) ,str) 180 (when ,start 181 (values 182 t 183 (substring ,str :start ,end) 184 (list (substring ,str :end ,end))))))))) 185 186 114 187 (defun make-sequence-parser (rules) 115 188 (with-gensyms (rule-parsers token-list) … … 133 206 (parse-eqcount ,count ,rule-parser ,token-list nil))))) 134 207 208 (defun make-maxcount-parser (count rule) 209 (with-gensyms (rule-parser token-list) 210 `(let ((,rule-parser ,(make-parser rule))) 211 (lambda (,token-list) 212 (parse-maxcount ,count ,rule-parser ,token-list nil))))) 213 214 (defun make-0or1-parser (rule) (make-maxcount-parser 1 rule)) 215 216 (defun make-+-parser (rule) 217 (with-gensyms (rule-parser token-list) 218 `(let ((,rule-parser ,(make-parser rule))) 219 (lambda (,token-list) 220 (parse-mincount 1 ,rule-parser ,token-list nil))))) 221 135 222 (defun make-required-pred (rule) 136 223 (with-gensyms (rule-parser token-list) … … 155 242 (when ,matched (values t ,rlist nil))))))) 156 243 244 (defmacro dispatch (sym fun) 245 `(progn 246 (when (cddr rule) (error ,(format nil "~A takes one argument" sym))) 247 (,fun (second rule)))) 248 157 249 (setf (symbol-function 'make-parser) (lambda (rule) 158 250 (etypecase rule 159 251 (symbol (make-token-parser rule)) 252 (character (make-character-parser rule)) 253 (string (make-regex-parser rule)) 160 254 (list 161 (case (first rule) 162 (& (make-required-pred (second rule))) 163 (! (make-forbidden-pred (second rule))) 164 (* (make-anycount-parser (cdr rule))) 165 (= (make-match-parser (cdr rule))) 166 (/ (make-choice-parser (cdr rule))) 167 (t (make-sequence-parser rule))))))) 255 (if (symbolp (first rule)) 256 (scase (first rule) 257 (& (dispatch & make-required-pred)) 258 (! (dispatch ! make-forbidden-pred)) 259 (* (dispatch * make-anycount-parser)) 260 (? (dispatch ? make-0or1-parser)) 261 (+ (dispatch + make-+-parser)) 262 (= (make-match-parser (cdr rule))) 263 (/ (make-choice-parser (cdr rule))) 264 (t (make-sequence-parser rule))) 265 (make-sequence-parser rule)))))) 168 266 169 267 … … 181 279 (let ((parser ,(make-parser rule))) 182 280 (multiple-value-bind (matched rlist mtree) (funcall parser token-list) 183 (when matched (values t rlist (list (quote ,name) mtree))))))) 281 (when matched 282 (values t rlist (list (append (list (quote ,name)) mtree)))))))) 184 283 185 284 (defun make-named-class (name rule) … … 203 302 `(progn 204 303 ,@(mapcar make definitions))))) 304 305 #| 306 dot-all 307 single-line 308 import section 309 skip tokens 310 |#
Note: See TracChangeset
for help on using the changeset viewer.
