Changeset trunk,11 for trunk/csv.lisp


Ignore:
Timestamp:
06/18/2007 07:51:03 PM (19 years ago)
Author:
dsowen
revision id:
svn-v3-trunk0:2948df59-2b31-0410-8e06-c40c0b09d5b6:trunk:11
Message:

Expanded CSV example.
Fixed: IF-MATCHES-PARSER was misspelled as IF-MATCHER-PARSER.
Adjusted tree construction for sequence matching.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/csv.lisp

    r9 r11  
     1(require '#:dso-lex)
    12(require '#:parse)
    23(require '#:cl-ppcre)
     4(use-package '#:dso-lex)
    35(import 'parse::substring)
    46(import 'parse::with-gensyms)
    57(import 'cl-ppcre:scan)
    6 (load "parse/parse3")
     8(load "lisp/parse/parse3")
    79
    8 (defmacro defparser (name rule)
     10
     11
     12(flet ((trim (s) (substring s :start 1 :length (- (length s) 2))))
     13  (defun un-squote (s)
     14    (cl-ppcre:regex-replace-all "''" (trim s) "'"))
     15  (defun un-dquote (s)
     16    (cl-ppcre:regex-replace-all "\"\"" (trim s) "\"")))
     17
     18(deflexer lex-csv
     19  ("," comma)
     20  ("\\n|\\r|\\r\\n" newline)
     21  ("'(?:[^']|'')*'" value un-squote)
     22  ("\"(?:[^\"]|\"\")*\"" value un-dquote)
     23  ("[^,'\"\\n\\r]+" value))
     24
     25(defun lex-all-csv (input &optional tokens)
     26  (multiple-value-bind (class image left) (lex-csv input)
     27    (if class
     28        (lex-all-csv left (cons (list class image) tokens))
     29        (nreverse tokens))))
     30
     31(defmacro defmatcher (class)
     32  (let ((fn-sym (intern (concatenate 'string "T-" (symbol-name class)))))
     33    `(defun ,fn-sym (token-list)
     34      (when token-list
     35        (destructuring-bind (class image) (first token-list)
     36          (when (eq class ',class)
     37            (values t (rest token-list) (list class image))))))))
     38
     39(defmatcher comma)
     40(defmatcher newline)
     41(defmatcher value)
     42
     43(defmacro defparser (name rule &optional filter)
    944  (with-gensyms (input next match)
    10   `(defun ,name (,input)
    11     (if-matches ,input ,rule (,next ,match)
    12       (values t ,next (list ',name ,match))))))
     45    `(defun ,name (,input)
     46      (if-matches ,input ,rule (,next ,match)
     47        (values t ,next (cons ',name ,(if filter `(,filter ,match) match)))))))
    1348
    1449(defmacro defgrammar (&body definitions)
    1550  (flet ((x (definition)
    16            (destructuring-bind (name rule) definition
    17              `(defparser ,name ,rule))))
     51           (destructuring-bind (name rule &optional filter) definition
     52             `(defparser ,name ,rule ,filter))))
    1853    `(progv () ,@(mapcar #'x definitions))))
    1954
    2055(defgrammar
    21   (file (+ row))
    22   (row (value (* ((= comma) value)) (= #\Newline)))
    23   (comma #\,)
    24   (value (? (/ dquoted-value squoted-value raw-value)))
    25   (dquoted-value (#\" (^ "(?:[^\"]|\"\")*") #\"))
    26   (squoted-value (#\' (^ "(?:[^']|'')*") #\'))
    27   (raw-value (^ "[^,'\"\\n]*")))
     56    (file (+ row))
     57  (row (t-value (* row-rest) (= t-newline))
     58       (lambda (row)
     59         (princ row)
     60         (mapcar #'second (cons (first row) (mapcar #'second (second row))))))
     61  (row-rest ((= t-comma) t-value) cdr))
    2862
    29 ;;; (deparser test (* (#\a #\b))) doesn't grab the match.
     63;;; (defparser test (* (#\a #\b))) doesn't grab the match.
Note: See TracChangeset for help on using the changeset viewer.