Index: /tags/dso-lex_0.1/lex.asd
===================================================================
--- /tags/dso-lex_0.1/lex.asd	(revision 5)
+++ /tags/dso-lex_0.1/lex.asd	(revision 5)
@@ -0,0 +1,5 @@
+;;;; -*- Mode: Lisp; Syntax: ANSI-Common-Lisp -*-
+
+(asdf:defsystem #:dso-lex
+  :depends-on (#:cl-ppcre)
+  :components ((:file "lex")))
Index: /tags/dso-lex_0.1/lex.lisp
===================================================================
--- /tags/dso-lex_0.1/lex.lisp	(revision 5)
+++ /tags/dso-lex_0.1/lex.lisp	(revision 5)
@@ -0,0 +1,31 @@
+(defpackage #:dso-lex
+  (:use #:cl #:cl-ppcre)
+  (:export #:deflexer))
+
+(in-package #:dso-lex)
+
+
+
+(defun combine (regex-list)
+  (let ((mapped (mapcar
+		 (lambda (regex) `(:register (:regex ,regex)))
+		 regex-list)))
+    (when (rest mapped) (setq mapped `((:alternation ,@mapped))))
+    `(:sequence (:flags :single-line-mode-p) :start-anchor
+      (:group ,@mapped)
+      (:register (:greedy-repetition 0 nil :everything)))))
+
+(defmacro deflexer (name &body body)
+  (let ((regex (combine (mapcar #'first body)))
+	(classes (map 'vector #'second body))
+	(filters (map 'vector #'third body)))
+    `(defun ,name (line)
+      (let ((parts
+	     (nth-value 1 (scan-to-strings (quote ,regex) line))))
+	(let ((idx (position-if #'identity parts)))
+	  (when idx
+	    (let ((token (aref parts idx))
+		  (filter (aref ,filters idx)))
+	      (values (aref ,classes idx)
+		      (if filter (funcall filter token) token)
+		      (aref parts ,(length classes))))))))))
