Changeset trunk,5 for trunk


Ignore:
Timestamp:
06/08/2007 03:19:22 AM (19 years ago)
Author:
dsowen
revision id:
svn-v3-trunk0:2948df59-2b31-0410-8e06-c40c0b09d5b6:trunk:5
Message:

Added string parser.
Added stub for regex parser.
Added inline decls.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/parse2.lisp

    r4 r5  
    44(import '(parse::with-gensyms parse::substring))
    55
    6 (defvar *follow* t)
     6(defvar *follow* nil)
    77
    88(defmacro follow (fmt &rest args)
    99  (when *follow*
    1010    `(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)))
    1123
    1224(defmacro with-character-parser ((name char) &body body)
     
    2032             (when (and (> (length ,input) 0) (char= (char ,input 0) ,char))
    2133               (values t (substring ,input :start 1) '(,char)))))
     34      (declare (inline ,name))
    2235      ,@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."))
    2354
    2455(defmacro with-sequence-parser% ((name seq) &body body)
     
    3667                         (,head ,input)
    3768                       (when ,matched (,tail ,left (append ,tree ,found))))))
     69              (declare (inline ,name))
    3870              ,@body)))
    3971        `(flet ((,name (,input ,tree)
     
    4173                 (declare (list ,tree))
    4274                 (values t ,input ,tree)))
     75          (declare (inline ,name))
    4376          ,@body))))
    4477
     
    5487                   (,subname ,input nil)
    5588                 (when ,matched (values t ,left (list ,found))))))
     89        (declare (inline ,name))
    5690        ,@body))))
    5791
     
    71105                           (values t ,left ,found)
    72106                           (,tail ,input)))))
     107              (declare (inline ,name))
    73108              ,@body)))
    74109        `(flet ((,name (,input)
    75110                 "Choice parser for base case."
    76111                 (declare (ignore ,input))))
     112          (declare (inline ,name))
    77113          ,@body))))
    78114
     
    85121               ,(format nil "Required parser for ~S." rule)
    86122               (when (,sub ,input) (values t ,input nil))))
     123        (declare (inline ,name))
    87124        ,@body))))
    88125
     
    95132               ,(format nil "Forbidden parser for ~S." rule)
    96133               (unless (,sub ,input) (values t ,input nil))))
     134        (declare (inline ,name))
    97135        ,@body))))
    98136
     
    110148                 ,(format nil "Range parser {~S, ~S} for ~S."
    111149                          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))
    131175          ,@body)))))
    132176
     
    135179  (follow "with-parser~%")
    136180  (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))
    139183    (list
    140184     (destructuring-bind (head . tail) rule
    141185       (case head
     186         (^ (destructuring-bind (regex) tail
     187              `(with-regex-parser (,name ,regex) ,@body)))
    142188         (/ `(with-choice-parser (,name ,tail) ,@body))
    143189         (& (destructuring-bind (subrule) tail
Note: See TracChangeset for help on using the changeset viewer.