Changeset trunk,2 for trunk


Ignore:
Timestamp:
06/01/2007 02:43:59 PM (19 years ago)
Author:
dsowen
revision id:
svn-v3-trunk0:2948df59-2b31-0410-8e06-c40c0b09d5b6:trunk:2
Message:

Packaged for ASDF.
Added character and regex support.
Added + and ? rules.

Location:
trunk
Files:
1 added
1 edited

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
    111(defstruct token
    212  class
     
    5969    ,@body))
    6070
     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
    6195
    6296
     
    98132        (when matched
    99133          (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)))
    100151      (values t token-list tree)))
    101152
     
    112163              (values t (rest ,token-list) (list ,token))))))))
    113164
     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
    114187(defun make-sequence-parser (rules)
    115188  (with-gensyms (rule-parsers token-list)
     
    133206        (parse-eqcount ,count ,rule-parser ,token-list nil)))))
    134207
     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
    135222(defun make-required-pred (rule)
    136223  (with-gensyms (rule-parser token-list)
     
    155242          (when ,matched (values t ,rlist nil)))))))
    156243
     244(defmacro dispatch (sym fun)
     245  `(progn
     246    (when (cddr rule) (error ,(format nil "~A takes one argument" sym)))
     247    (,fun (second rule))))
     248
    157249(setf (symbol-function 'make-parser) (lambda (rule)
    158250  (etypecase rule
    159251    (symbol (make-token-parser rule))
     252    (character (make-character-parser rule))
     253    (string (make-regex-parser rule))
    160254    (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))))))
    168266
    169267
     
    181279    (let ((parser ,(make-parser rule)))
    182280      (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))))))))
    184283
    185284(defun make-named-class (name rule)
     
    203302      `(progn
    204303        ,@(mapcar make definitions)))))
     304
     305#|
     306dot-all
     307single-line
     308import section
     309skip tokens
     310|#
Note: See TracChangeset for help on using the changeset viewer.