-
Notifications
You must be signed in to change notification settings - Fork 1
/
tokenizer.lisp
32 lines (27 loc) · 1.16 KB
/
tokenizer.lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
(defclass tokenizer ()
((tokens :initform nil
:accessor tkns)))
(defmethod next-token-p ((tokenizer tokenizer))
(not (null (slot-value tokenizer 'tokens))))
(defmethod next-token ((tokenizer tokenizer))
(let ((slot (slot-value tokenizer 'tokens)))
(setf (slot-value tokenizer 'tokens) (cdr slot))
(car slot)))
(defun make-tokenizer (str &optional (delim #\space))
(let ((tokener (make-instance 'tokenizer)))
(setf (slot-value tokener 'tokens) (split-on-delim str delim))
tokener))
(defun split-on-delim (str delim)
(do* ((start 0 (1+ end))
(end (position delim str) (position delim str :start start))
(result (if (and (eql delim #\space) (eql start end))
nil
(list (subseq str start end)))
(if (and (eql delim #\space) (or (eql start end) (null end)))
result
(cons (subseq str start end) result))))
((null end) (reverse result))))
(defun split-string (str &optional delim)
(let ((tokenizer (make-tokenizer str delim)))
(do ((l nil (cons (next-token tokenizer) l)))
((not (next-token-p tokenizer)) (nreverse l)))))