Changeset trunk,3 for trunk/parse.lisp
- Timestamp:
- 06/07/2007 10:11:03 PM (19 years ago)
- revision id:
- svn-v3-trunk0:2948df59-2b31-0410-8e06-c40c0b09d5b6:trunk:3
- File:
-
- 1 edited
-
trunk/parse.lisp (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/parse.lisp
r2 r3 8 8 9 9 10 11 10 (defstruct token 12 11 class 13 12 string) 14 15 #|16 (defmacro defparser (name &body body))17 18 (defparser blah19 / (simple ident) ; matches token class20 / (seq-ex (e1 e2)) ; matches e1 followed by e221 / (choice-ex (/ e1 e2)) ; matches e1, or else e222 / (not-ex (! e1 e2)) ; matches if not e1, and if not e223 / (require-ex (& e1 e2)) ; matches if e1, and if e2 (pointless)24 (kleene-ex1 (* e1 e2)) ; matches e1* e2*25 (kleene-ex2 (* (e1 e2))) ; matches (e1 e2)*26 (req-ex1 (+ e1 e2)) ; matches e1+ e2+27 (req-ex2 (+ (e1 e2))) ; (e1 e2)+28 (match-only (: e1 e2)) ; matches and consumes, but29 ; doesn't emit30 (match-only (: (e1 e2))))31 32 (defparser minijava-parser33 (program (main-class (* class-decl)))34 (main-class35 ((: class)36 ident37 (: lbrace public static void main lparen string lbracket rbracket ident38 rparen lbrace)39 statement40 (: rbrace rbrace)))41 (ident id)42 (statement (/ block if while print assign array-assign))43 (block ((: lbrace) (* statement) (: rbrace)))44 (if ((: if lparen) exp (: rparen) statement (: else) statement))45 (while ((: while lparen) exp (: rparen) statement))46 (print ((: sop lparen) exp (: rparen semicolon)))47 (exp (/ num)))48 49 (class (id "A") lbrace public static void main lparen string lbracket rbracket50 (id "args") rparen lbrace sop lparen (num 0) rparen semicolon rbrace51 rbrace)52 53 (program54 (main-class55 (ident "A")56 (statement57 (print58 (num 0)))))59 |#60 61 13 62 14 ;;;; A parser returns, as a list, all parts matched; and, the … … 91 43 clauses))))) 92 44 45 (defmacro specials ((&body decls) &body body) 46 "Like LET, but declares the bound variables to be special." 47 `(let ,decls 48 (declare (special ,@(mapcar #'first decls))) 49 ,@body)) 50 51 (defun as-list (item) (if (listp item) item (list item))) 52 93 53 94 54 … … 153 113 154 114 115 ;; This needs to be changed to just use the function of the given 116 ;; symbol-name, so that any format of sequence may be supported. 155 117 (defun make-token-parser (token-class) 156 (declare (special definition-names)) 118 (declare (special definition-names 119 *import*)) 120 (unless (or (member token-class definition-names) 121 (member token-class *import*)) 122 (warn "Parser ~A is neither defined nor imported." token-class)) 157 123 (if (member token-class definition-names) 158 124 `(function ,token-class) … … 173 139 174 140 (defun make-regex-parser (regex) 175 (let ((regex `(:sequence (:flags :single-line-mode-p) :start-anchor 141 (declare (special *regex-flags*)) 142 (let ((regex `(:sequence (:flags ,@*regex-flags*) :start-anchor 176 143 (:register (:regex ,regex))))) 177 144 (with-gensyms (str start end) … … 276 243 277 244 (defun make-named-parser (name rule) 245 (declare (special *filter*)) 278 246 `(defun ,name (token-list) 279 247 (let ((parser ,(make-parser rule))) 280 248 (multiple-value-bind (matched rlist mtree) (funcall parser token-list) 281 249 (when matched 282 (values t rlist (list (append (list (quote ,name)) mtree)))))))) 250 (values t 251 rlist 252 ,(if *filter* 253 `(list (append (list (quote ,name)) (,*filter* mtree))) 254 `(list (append (list (quote ,name)) mtree)) 255 ))))))) 283 256 284 257 (defun make-named-class (name rule) 258 (declare (special *filter*)) 285 259 `(defun ,name (token-list) 286 260 (let ((parser ,(make-parser rule))) 287 (funcall parser token-list)))) 288 289 (defun make-named (class-names definition) 290 (let ((name (car definition)) 291 (rule (cadr definition))) 292 (if (member name class-names) 293 (make-named-class name rule) 294 (make-named-parser name rule)))) 295 296 (defmacro defgrammar (classes &body definitions) 297 (let ((definition-names (mapcar #'first definitions))) 298 (declare (special definition-names)) 299 (let ((rule-map (hash-names definition-names)) 300 (make (lambda (definition) (make-named classes definition)))) 301 (declare (special rule-map)) 261 ,(if *filter* 262 `(multiple-value-bind (matched rlist mtree) 263 (funcall parser token-list) 264 (when matched 265 (values t rlist (,*filter* mtree)))) 266 `(funcall parser token-list))))) 267 268 (defun make-named (definition) 269 (declare (special *classes*)) 270 (destructuring-bind (name rule &key filter) definition 271 (specials ((*filter* filter)) 272 (if (member name *classes*) 273 (make-named-class name rule) 274 (make-named-parser name rule))))) 275 276 (defmacro defgrammar ((&key classes import regex-flags skip) 277 &body definitions) 278 (specials ((*classes* classes) 279 (*import* import) ; used only for warnings 280 (*regex-flags* (as-list regex-flags)) 281 (*skip* skip) ; unused 282 (definition-names (mapcar #'first definitions))) 283 (let ((rule-map (hash-names definition-names))) 302 284 `(progn 303 ,@(mapcar makedefinitions)))))285 ,@(mapcar #'make-named definitions))))) 304 286 305 287 #| 306 dot-all 307 single-line 308 import section 309 skip tokens 288 dot-all dot recognizes line-breaks 289 single-line matches extend across lines 290 import section supress warnings 291 skip tokens automatically allow these between all parts 310 292 |#
Note: See TracChangeset
for help on using the changeset viewer.
