Mercurial > core / lisp/lib/parse/lex.lisp
changeset 698: |
96958d3eb5b0 |
parent: |
686748796f08
|
author: |
Richard Westhaver <ellis@rwest.io> |
date: |
Fri, 04 Oct 2024 22:04:59 -0400 |
permissions: |
-rw-r--r-- |
description: |
fixes |
1 ;;; lib/parse/lex.lisp --- Lexer Tools 3 ;; https://github.com/Shinmera/plump/blob/master/lexer.lisp 7 ;; TODO: make less dynamic, compile lexer functions for compatibility 11 (in-package :parse/lex) 12 (declaim (optimize (speed 3) (safety 1))) 16 (defvar *matchers* (make-hash-table)) 17 (declaim (fixnum *length* *index*) 18 (simple-string *string*) 19 (hash-table *matchers*)) 21 (defmacro with-lexer-environment ((string) &body body) 22 `(let* ((*string* ,string) 23 (*string* (etypecase *string* 24 (simple-string *string*) 25 (string (copy-seq *string*)))) 26 (*length* (length *string*)) 28 (handler-bind ((error #'(lambda (err) 29 (declare (ignore err)) 30 (format T "Error during lexing at index ~a~%" *index*)))) 33 (declaim (ftype (function () (or character null)) consume) 36 (declare (optimize (speed 3) (safety 0))) 37 (when (< *index* *length*) 38 (prog1 (aref *string* *index*) 39 #+debug (format T "~a +~%" *index*) 42 (declaim (ftype (function () (or fixnum null)) advance) 45 (declare (optimize (speed 3) (safety 0))) 46 (when (< *index* *length*) 47 #+debug (format T "~a +~%" *index*) 50 (declaim (ftype (function () fixnum) unread) 53 (declare (optimize (speed 3) (safety 0))) 55 #+debug (format T "~a -~%" *index*) 59 (declaim (ftype (function () (or character null)) peek) 62 (declare (optimize (speed 3) (safety 0))) 63 (when (< *index* *length*) 64 #+debug (format T "~a ?~%" *index*) 65 (aref *string* *index*))) 67 (declaim (ftype (function (fixnum) fixnum) advance-n) 70 (declare (optimize (speed 3) (safety 0))) 72 #+debug (format T "~a +~d~%" *index* n) 74 (when (<= *length* *index*) 75 (setf *index* *length*)) 78 (declaim (ftype (function (fixnum) fixnum) unread-n) 81 (declare (optimize (speed 3) (safety 0))) 83 #+debug (format T "~a -~d~%" *index* n) 89 (declaim (ftype (function (function) string) consume-until)) 90 (defun consume-until (matcher) 91 (declare (function matcher)) 92 (loop with start = *index* 93 until (funcall matcher) 95 finally (return (subseq *string* start *index*)))) 97 (declaim (ftype (function (character) function) matcher-character)) 98 (defun matcher-character (character) 102 (char= char character))))) 104 (declaim (ftype (function (simple-string) function) matcher-string)) 105 (defun matcher-string (string) 106 (declare (simple-string string)) 107 (let ((len (length string))) 109 (let ((len (+ *index* len))) 110 (and (<= len *length*) 111 (string= string *string* :start2 *index* :end2 len)))))) 113 (declaim (ftype (function ((or fixnum character string) (or fixnum character string)) function) matcher-range)) 114 (defun matcher-range (from to) 115 (flet ((normalize (in) (etypecase in 117 (character (char-code in)) 118 (simple-string (char-code (char in 0)))))) 119 (let ((from (normalize from)) 124 (<= from (char-code char) to))))))) 126 (declaim (ftype (function (list) function) matcher-find)) 127 (defun matcher-find (list) 130 (and char (member char list :test #'char=))))) 132 (declaim (ftype (function (&rest function) function) matcher-or)) 133 (defun matcher-or (&rest matchers) 135 (loop for matcher of-type function in matchers 136 thereis (funcall matcher)))) 138 (declaim (ftype (function (&rest function) function) matcher-and)) 139 (defun matcher-and (&rest matchers) 141 (loop for matcher of-type function in matchers 142 always (funcall matcher)))) 144 (declaim (ftype (function (function) function) matcher-not)) 145 (defun matcher-not (matcher) 146 (declare (function matcher)) 148 (not (funcall matcher)))) 150 (declaim (ftype (function (function) function) matcher-next)) 151 (defun matcher-next (matcher) 153 (let ((*index* (1+ *index*))) 154 (when (< *index* *length*) 155 (funcall matcher))))) 157 (declaim (ftype (function (function) function) matcher-prev)) 158 (defun matcher-prev (matcher) 160 (let ((*index* (1- *index*))) 162 (funcall matcher))))) 164 (defmacro matcher-any (&rest is) 165 `(matcher-or ,@(loop for i in is 166 collect `(,(typecase i 167 (string 'matcher-string) 168 (character 'matcher-character) 169 (T 'matcher-string)) ,i)))) 171 (defmacro make-matcher (form) 172 (labels ((transform (form) 175 `(gethash ',form *matchers*)) 179 (case (find-symbol (string (car form)) "PARSE/LEX") 183 (is (typecase (second form) 184 (string 'matcher-string) 185 (character 'matcher-character) 186 (T 'matcher-string))) 193 (mapcar #'transform (cdr form))))))) 196 (defmacro define-matcher (name form) 197 `(setf (gethash ,(intern (string name) "KEYWORD") *matchers*) (make-matcher ,form)))