(in-package :json) (defparameter *json* "{\"hello\": 55}") (defclass json-okur () ((arabellek :accessor arabellek :initarg :arabellek :type string) (uzunluk :accessor uzunluk :initarg :uzunluk :type integer) (i :accessor i :initform 0 :type integer) (ch :accessor ch :type character) (ch2 :accessor ch2 :type character))) (defparameter +eof+ (code-char 0)) (defun eof? (ch) (char= +eof+ ch)) (defun yeni (arabellek &optional (uzunluk (length arabellek))) (let ((okur (make-instance 'json-okur :arabellek arabellek :uzunluk uzunluk))) (char-gözat! okur) okur)) (defmethod reset ((o json-okur)) (setf (i o) 0) (char-gözat! o)) (defmethod index ((o json-okur)) (- (i o) 2)) (defmethod char-oynat ((o json-okur)) (setf (ch o) (ch2 o)) (char-gözat! o) (ch o)) (defmethod char-gözat ((o json-okur)) (ch2 o)) (defmethod char-gözat! ((o json-okur)) "Sonraki karaktere bak ve kaydet" (with-slots (i uzunluk arabellek ch2) o (cond ((array-in-bounds-p arabellek i) (setf ch2 (aref arabellek i)) (incf i)) (t (setf ch2 +eof+))))) (defun boşluk? (ch) (find ch #(#\Space #\Newline #\Return #\Tab))) (defmethod boşluk-geç ((o json-okur)) (loop :while (boşluk? (char-gözat o)) :do (char-oynat o))) (defmethod metin-oku ((o json-okur)) (let* ((baş (+ 1 (index o)))) (loop :for char := (char-oynat o) :until (char= #\" char)) (subseq (arabellek o) baş (index o)))) (defmethod rakam? (ch) (char<= #\0 ch #\9)) (defmethod sayı-oku ((o json-okur)) (let* ((baş (index o))) (loop :for char := (char-gözat o) :while (rakam? char) :do (char-oynat o)) (subseq (arabellek o) baş (+ 1 (index o))))) (defmethod token-oku ((o json-okur)) (case (char-oynat o) (#\{ :süslü-aç) (#\} :süslü-kapa) (#\: :iki-nokta) (#\" (list :string (metin-oku o))) (otherwise (cond ((rakam? (ch o)) (list :sayı (sayı-oku o))) ((boşluk? (ch o)) (boşluk-geç o)) ((eof? (ch o)) :eof))))) (defmethod işle ((o json-okur)) (loop :for token := (token-oku o) :collect token :until (eq :eof token)))