dear list,
as a followup, please find the current version attached. unfortunately i was drawn away from this code, but it works well when working with gccxml outputs.
the following code fragments are from a new, halfdone version of verrazano. it parses a gccxml output into clos objects that are later used in multiple dispatch. the classes must be precreated for safety/sanity, but they could be automatically created, too. stuff that is gccxml specific is prefixed with gccxml: for clarity.
slots with 'flexml:cross-referenced-node(s) type are automatically resolved to the referenced nodes through the id attribute.
(defclass gccxml-parser (flexml:flexml-builder) ((macro-name->macro-node :initform (make-hash-table :test #'equal) :accessor macro-name->macro-node-of) (type->name->node :initform (make-hash-table :test #'eq) :accessor type->name->node-of) (id->file-node :initform (make-hash-table :test #'equal) :accessor id->file-node-of) (input-files :initform (make-hash-table :test #'eq) :accessor input-files-of)))
(defun make-gccxml-parser () (make-instance 'gccxml-parser :default-package "GCCXML"))
(defclass gccxml:node (flexml:flexml-node) ((gccxml:file :initform nil :type flexml:cross-referenced-node :accessor gccxml:file-of) (gccxml:line :initform nil :type (or null integer) :accessor gccxml:line-of) (gccxml:context :initform nil :type flexml:cross-referenced-node :accessor gccxml:context-of)))
(defclass gccxml:node-with-name (gccxml:node) ((gccxml:name :initform nil :accessor gccxml:name-of)))
(defclass gccxml:node-with-type (gccxml:node) ((gccxml:type :type flexml:cross-referenced-node :accessor gccxml:type-of)))
(defclass gccxml:node-with-members (gccxml:node) ((gccxml:members :initform #() :type flexml:cross-referenced-nodes :accessor gccxml:members-of)))
(defclass gccxml:definition (gccxml:node-with-name) ())
(defclass gccxml:externable-node (gccxml:definition) ((gccxml:extern :type boolean :accessor gccxml:extern?)))
(macrolet ((define (&body entries) `(progn ,@(iter (for entry :in entries) (destructuring-bind (name &optional (supers '(gccxml:node)) &body slots) (ensure-list entry) (collect `(defclass ,name ,supers (,@slots)))))))) (define gccxml:gcc_xml (gccxml:namespace (gccxml:node-with-name gccxml:node-with-type gccxml:node-with-members)) (gccxml:variable (gccxml:externable-node gccxml:node-with-type)) (gccxml:function (gccxml:externable-node) (gccxml:returns :type flexml:cross-referenced-node :accessor gccxml:returns-of)) (gccxml:argument (gccxml:node-with-name gccxml:node-with-type)) gccxml:ellipsis (gccxml:enumeration (gccxml:definition)) (gccxml:enumvalue (gccxml:node-with-name)) (gccxml:struct (gccxml:definition gccxml:node-with-members) (gccxml:incomplete :initform nil :type boolean :accessor gccxml:incomplete?)) (gccxml:union (gccxml:definition gccxml:node-with-members)) (gccxml:typedef (gccxml:definition gccxml:node-with-type)) (gccxml:fundamentaltype (gccxml:node-with-name)) (gccxml:pointertype (gccxml:node-with-type)) (gccxml:arraytype (gccxml:node-with-type)) (gccxml:functiontype (gccxml:definition) (gccxml:returns :type flexml:cross-referenced-node)) (gccxml:cvqualifiedtype (gccxml:node-with-type)) gccxml:referencetype (gccxml:field (gccxml:node-with-name gccxml:node-with-type) (gccxml:bits :initform nil :type (or null integer) :accessor gccxml:bits-of) (gccxml:offset :type integer :accessor gccxml:offset-of)) gccxml:constructor (gccxml:file (gccxml:node-with-name)) (gccxml:macro (gccxml:definition) (gccxml:name :accessor gccxml:name-of) (gccxml:arguments :initform nil :accessor gccxml:arguments-of) (gccxml:body :accessor gccxml:body-of) (gccxml:raw-body :accessor gccxml:raw-body-of))))
(defun parse-gccxml-output (gccxml-file &optional macros-file) (bind ((*parser* (make-gccxml-parser))) (cxml:parse gccxml-file *parser*) (when macros-file (parse-macro-definitions macros-file)) *parser*))