Re: Translating parse result into instances
- From: Ari Johnson <iamtheari@xxxxxxxxx>
- Date: Thu, 30 Aug 2007 18:13:09 -0500
Frank Goenninger DG1SBG <dont-email-me@xxxxxxxxxx> writes:
I need to create a Model instance with ID slot being bound to
:frgo. Next I want to create Polygon instances ... You get the idea.
New one for me, really. What if this goes to some few hundreds of
polygons... So I am looking not for complete code just for a few
pointers/hints which route to go. Loop? Mapcar combined with a large
cond or so?
This is what my idea looks like. You could replace some parts with
MAPCAR if you wanted to do so. Note that this is clearly not
complete, but is a good start toward what you want to accomplish and
is extensible to handle other types of data if you want to do so.
I don't know why you ask what would happen if it went to several
hundred polygons. It'll use more memory, proportionate to the number
of polygons, of course, but the code below is O(n) so you shouldn't
worry about things blowing up before you run out of memory.
(defclass model ()
((id :initarg id :accessor id)
(elements :initarg elements :initform '() :accessor elements)))
(defclass polygon ()
((color :initarg color :accessor color)
(class :initarg class :accessor class)
(points :initarg points :initform '() :accessor points)))
(defclass point ()
((data :initarg data :accessor data)))
(defmacro string-case (key &body forms)
`(cond ,@(mapcar (lambda (form)
(if (eq (car form) t)
`(t ,@(cdr form))
`((string= ,key ,(car form))
,@(cdr form))))
forms)))
(defun parse-model (data)
(string-case (car data)
("model" (%parse-model% data))
(t (error "Unknown model type ~S" (car data)))))
(defun %parse-model% (data)
(destructuring-bind (type attributes &rest elements)
data
(let ((model (make-instance 'model)))
(loop :for attribute :in attributes
:do (string-case (car attribute)
("id" (setf (id model) (cadr attribute)))
(t (error "Unknown model attribute ~S" (car attribute)))))
(let ((parsed-elements '()))
(loop :for element :in elements
:do (push (parse-element element) parsed-elements))
(setf (elements model) (nreverse parsed-elements)))
model)))
(defun parse-element (data)
(string-case (car data)
("polygon" (%parse-polygon% data))
(t (error "Unknown element type ~S" (car data)))))
(defun %parse-polygon% (data)
(destructuring-bind (type attributes structure)
data
(let ((polygon (make-instance 'polygon)))
(loop :for attribute :in attributes
:do (string-case (car attribute)
("color" (setf (color polygon) (cadr attribute)))
("class" (setf (class polygon) (cadr attribute)))
(t (error "Unknown polygon attribute ~S" (car attribute)))))
(destructuring-bind (structure-type structure-attributes &rest elements)
structure
(string-case structure-type
("points"
(let ((npoints nil)
(points '()))
(loop :for attribute :in structure-attributes
:do (string-case (car attribute)
("n" (setf npoints (parse-integer (cadr attribute))))
(t (error "Unknown points structure attribute ~S"
(car attribute)))))
(unless npoints
(warn "Points structure lacks \"n\" attribute"))
(loop :for point :in elements
:do (push (parse-point point) points))
(when npoints
(unless (= npoints (length points))
(warn "Points structure has incorrect \"n\" attribute")))
(setf (points polygon) (nreverse points))))
(t (error "Unknown structure type ~S" structure-type))))
polygon)))
(defun parse-point (data)
data)
.
- References:
- Translating parse result into instances
- From: Frank Goenninger DG1SBG
- Translating parse result into instances
- Prev by Date: Re: Tab-completion (for CLISP) in inferior-lisp-mode in Emacs; possible?
- Next by Date: Re: Tab-completion (for CLISP) in inferior-lisp-mode in Emacs; possible?
- Previous by thread: Translating parse result into instances
- Next by thread: Re: Translating parse result into instances
- Index(es):