1 ;;; Copyright (c) 2007 David Lichteblau. All rights reserved.
3 ;;; Redistribution and use in source and binary forms, with or without
4 ;;; modification, are permitted provided that the following conditions
7 ;;; * Redistributions of source code must retain the above copyright
8 ;;; notice, this list of conditions and the following disclaimer.
10 ;;; * Redistributions in binary form must reproduce the above
11 ;;; copyright notice, this list of conditions and the following
12 ;;; disclaimer in the documentation and/or other materials
13 ;;; provided with the distribution.
15 ;;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED
16 ;;; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17 ;;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 ;;; ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
19 ;;; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 ;;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
21 ;;; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 ;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 ;;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 ;;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 ;;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 (in-package :cxml-rng
)
30 (declaim (optimize (debug 2)))
35 (define-condition rng-error
(simple-error) ())
37 (defun rng-error (source fmt
&rest args
)
38 (let ((s (make-string-output-stream)))
39 (apply #'format s fmt args
)
43 (format s
"~& [ Error at line ~D, column ~D in ~S ]"
44 (klacks:current-line-number source
)
45 (klacks:current-column-number source
)
46 (klacks:current-system-id source
)))
48 (format s
"~& [ Error at line ~D, column ~D in ~S ]"
49 (sax:line-number source
)
50 (sax:column-number source
)
51 (sax:system-id source
))) ))
54 :format-arguments
(list (get-output-stream-string s
)))))
59 (defvar *datatype-library
*)
60 (defvar *namespace-uri
*)
62 (defvar *entity-resolver
*)
63 (defvar *external-href-stack
*)
64 (defvar *include-uri-stack
*)
65 (defvar *include-body-p
* nil
)
70 (defstruct (parsed-grammar (:constructor make-parsed-grammar
(pattern)))
71 (pattern (missing) :type pattern
)
72 (interned-start nil
:type
(or null pattern
))
73 (registratur nil
:type
(or null hash-table
)))
75 (defun invoke-with-klacks-handler (fn source
)
80 (cxml:xml-parse-error
(c)
81 (rng-error source
"Cannot parse schema: ~A" c
)))))
83 (defun parse-relax-ng (input &key entity-resolver
)
84 (klacks:with-open-source
(source (cxml:make-source input
))
85 (invoke-with-klacks-handler
87 (klacks:find-event source
:start-element
)
88 (let* ((*datatype-library
* "")
90 (*entity-resolver
* entity-resolver
)
91 (*external-href-stack
* '())
92 (*include-uri-stack
* '())
93 (*grammar
* (make-grammar nil
))
94 (result (p/pattern source
)))
96 (rng-error nil
"empty grammar"))
97 (setf (grammar-start *grammar
*)
98 (make-definition :name
:start
:child result
))
99 (check-pattern-definitions source
*grammar
*)
100 (check-recursion result
0)
101 (setf result
(fold-not-allowed result
))
102 (setf result
(fold-empty result
))
103 (make-parsed-grammar result
)))
107 ;;;; pattern structures
111 (defstruct (%parent
(:include pattern
) (:conc-name
"PATTERN-"))
114 (defstruct (%named-pattern
(:include %parent
) (:conc-name
"PATTERN-"))
116 (defstruct (element (:include %named-pattern
) (:conc-name
"PATTERN-")))
117 (defstruct (attribute (:include %named-pattern
) (:conc-name
"PATTERN-")))
119 (defstruct (%combination
(:include pattern
) (:conc-name
"PATTERN-"))
122 (:include %combination
)
123 (:constructor make-group
(a b
))))
124 (defstruct (interleave
125 (:include %combination
)
126 (:constructor make-interleave
(a b
))))
128 (:include %combination
)
129 (:constructor make-choice
(a b
))))
131 (:include %combination
)
132 (:constructor make-after
(a b
))))
134 (defstruct (one-or-more
136 (:constructor make-one-or-more
(child))))
137 (defstruct (list-pattern
139 (:constructor make-list-pattern
(child))))
143 (:conc-name
"PATTERN-")
144 (:constructor make-ref
(target)))
148 (defstruct (%leaf
(:include pattern
)))
150 (defstruct (empty (:include %leaf
) (:conc-name
"PATTERN-")))
151 (defstruct (text (:include %leaf
) (:conc-name
"PATTERN-")))
153 (defstruct (%typed-pattern
(:include %leaf
) (:conc-name
"PATTERN-"))
157 (defstruct (value (:include %typed-pattern
) (:conc-name
"PATTERN-"))
161 (defstruct (data (:include %typed-pattern
) (:conc-name
"PATTERN-"))
165 (defstruct (not-allowed (:include %leaf
) (:conc-name
"PATTERN-")))
170 (defstruct (grammar (:constructor make-grammar
(parent)))
173 (definitions (make-hash-table :test
'equal
)))
179 ;; Clark calls this structure "RefPattern"
180 (defstruct (definition (:conc-name
"DEFN-"))
191 (error "missing arg"))
193 (defstruct name-class
)
195 (defstruct (any-name (:include name-class
)
196 (:constructor make-any-name
(except)))
197 (except (missing) :type
(or null name-class
)))
199 (defstruct (name (:include name-class
)
200 (:constructor make-name
(uri lname
)))
201 (uri (missing) :type string
)
202 (lname (missing) :type string
))
204 (defstruct (ns-name (:include name-class
)
205 (:constructor make-ns-name
(uri except
)))
206 (uri (missing) :type string
)
207 (except (missing) :type
(or null name-class
)))
209 (defstruct (name-class-choice (:include name-class
)
210 (:constructor make-name-class-choice
(a b
)))
211 (a (missing) :type name-class
)
212 (b (missing) :type name-class
))
214 (defun simplify-nc-choice (values)
215 (zip #'make-name-class-choice values
))
220 (defvar *rng-namespace
* "http://relaxng.org/ns/structure/1.0")
222 (defun skip-foreign* (source)
224 (case (klacks:peek-next source
)
225 (:start-element
(skip-foreign source
))
226 (:end-element
(return)))))
228 (defun skip-to-native (source)
230 (case (klacks:peek source
)
232 (when (equal (klacks:current-uri source
) *rng-namespace
*)
234 (klacks:serialize-element source nil
))
235 (:end-element
(return)))
236 (klacks:consume source
)))
238 (defun consume-and-skip-to-native (source)
239 (klacks:consume source
)
240 (skip-to-native source
))
242 (defun skip-foreign (source)
243 (when (equal (klacks:current-uri source
) *rng-namespace
*)
245 "invalid schema: ~A not allowed here"
246 (klacks:current-lname source
)))
247 (klacks:serialize-element source nil
))
249 (defun attribute (lname attrs
)
250 (let ((a (sax:find-attribute-ns
"" lname attrs
)))
252 (sax:attribute-value a
)
255 (defparameter *whitespace
*
256 (format nil
"~C~C~C~C"
262 (defun ntc (lname source-or-attrs
)
263 ;; used for (n)ame, (t)ype, and (c)ombine, this also strings whitespace
265 (if (listp source-or-attrs
)
267 (klacks:list-attributes source-or-attrs
)))
268 (a (sax:find-attribute-ns
"" lname attrs
)))
270 (string-trim *whitespace
* (sax:attribute-value a
))
273 (defmacro with-library-and-ns
(attrs &body body
)
274 `(invoke-with-library-and-ns (lambda () ,@body
) ,attrs
))
276 (defun invoke-with-library-and-ns (fn attrs
)
277 (let* ((dl (attribute "datatypeLibrary" attrs
))
278 (ns (attribute "ns" attrs
))
279 (*datatype-library
* (if dl
(escape-uri dl
) *datatype-library
*))
280 (*namespace-uri
* (or ns
*namespace-uri
*))
284 (defun p/pattern
(source)
285 (let* ((lname (klacks:current-lname source
))
286 (attrs (klacks:list-attributes source
)))
287 (with-library-and-ns attrs
288 (case (find-symbol lname
:keyword
)
289 (:|element|
(p/element source
(ntc "name" attrs
)))
290 (:|attribute|
(p/attribute source
(ntc "name" attrs
)))
291 (:|group|
(p/combination
#'groupify source
))
292 (:|interleave|
(p/combination
#'interleave-ify source
))
293 (:|choice|
(p/combination
#'choice-ify source
))
294 (:|optional|
(p/optional source
))
295 (:|zeroOrMore|
(p/zero-or-more source
))
296 (:|oneOrMore|
(p/one-or-more source
))
297 (:|list|
(p/list source
))
298 (:|mixed|
(p/mixed source
))
299 (:|ref|
(p/ref source
))
300 (:|parentRef|
(p/parent-ref source
))
301 (:|empty|
(p/empty source
))
302 (:|text|
(p/text source
))
303 (:|value|
(p/value source
))
304 (:|data|
(p/data source
))
305 (:|notAllowed|
(p/not-allowed source
))
306 (:|externalRef|
(p/external-ref source
))
307 (:|grammar|
(p/grammar source
))
308 (t (skip-foreign source
))))))
310 (defun p/pattern
+ (source)
311 (let ((children nil
))
313 (case (klacks:peek source
)
315 (let ((p (p/pattern source
))) (when p
(push p children
))))
319 (klacks:consume source
))))
321 (rng-error source
"empty element"))
322 (nreverse children
)))
324 (defun p/pattern?
(source)
327 (skip-to-native source
)
328 (case (klacks:peek source
)
331 (rng-error source
"at most one pattern expected here"))
332 (setf result
(p/pattern source
)))
336 (klacks:consume source
))))
339 (defun p/element
(source name
)
340 (klacks:expecting-element
(source "element")
341 (let ((result (make-element)))
342 (consume-and-skip-to-native source
)
344 (setf (pattern-name result
) (destructure-name source name
))
345 (setf (pattern-name result
) (p/name-class source
)))
346 (skip-to-native source
)
347 (setf (pattern-child result
) (groupify (p/pattern
+ source
)))
350 (defvar *attribute-namespace-p
* nil
)
352 (defun p/attribute
(source name
)
353 (klacks:expecting-element
(source "attribute")
354 (let ((result (make-attribute)))
355 (consume-and-skip-to-native source
)
357 (setf (pattern-name result
)
358 (let ((*namespace-uri
* (or *ns
* "")))
359 (destructure-name source name
)))
360 (setf (pattern-name result
)
361 (let ((*attribute-namespace-p
* t
))
362 (p/name-class source
))))
363 (skip-to-native source
)
364 (setf (pattern-child result
)
365 (or (p/pattern? source
) (make-text)))
368 (defun p/combination
(zipper source
)
369 (klacks:expecting-element
(source)
370 (consume-and-skip-to-native source
)
371 (funcall zipper
(p/pattern
+ source
))))
373 (defun p/one-or-more
(source)
374 (klacks:expecting-element
(source "oneOrMore")
375 (consume-and-skip-to-native source
)
376 (let ((children (p/pattern
+ source
)))
377 (make-one-or-more (groupify children
)))))
379 (defun p/zero-or-more
(source)
380 (klacks:expecting-element
(source "zeroOrMore")
381 (consume-and-skip-to-native source
)
382 (let ((children (p/pattern
+ source
)))
383 (make-choice (make-one-or-more (groupify children
))
386 (defun p/optional
(source)
387 (klacks:expecting-element
(source "optional")
388 (consume-and-skip-to-native source
)
389 (let ((children (p/pattern
+ source
)))
390 (make-choice (groupify children
) (make-empty)))))
392 (defun p/list
(source)
393 (klacks:expecting-element
(source "list")
394 (consume-and-skip-to-native source
)
395 (let ((children (p/pattern
+ source
)))
396 (make-list-pattern (groupify children
)))))
398 (defun p/mixed
(source)
399 (klacks:expecting-element
(source "mixed")
400 (consume-and-skip-to-native source
)
401 (let ((children (p/pattern
+ source
)))
402 (make-interleave (groupify children
) (make-text)))))
404 (defun p/ref
(source)
405 (klacks:expecting-element
(source "ref")
407 (let* ((name (ntc "name" source
))
409 (or (find-definition name
)
410 (setf (find-definition name
)
411 (make-definition :name name
:child nil
)))))
412 (make-ref pdefinition
))
413 (skip-foreign* source
))))
415 (defun p/parent-ref
(source)
416 (klacks:expecting-element
(source "parentRef")
418 (let* ((name (ntc "name" source
))
419 (grammar (grammar-parent *grammar
*))
421 (or (find-definition name grammar
)
422 (setf (find-definition name grammar
)
423 (make-definition :name name
:child nil
)))))
424 (make-ref pdefinition
))
425 (skip-foreign* source
))))
427 (defun p/empty
(source)
428 (klacks:expecting-element
(source "empty")
429 (skip-foreign* source
)
432 (defun p/text
(source)
433 (klacks:expecting-element
(source "text")
434 (skip-foreign* source
)
437 (defun consume-and-parse-characters (source)
441 (multiple-value-bind (key data
) (klacks:peek-next source
)
444 (setf tmp
(concatenate 'string tmp data
)))
445 (:end-element
(return)))))
448 (defun p/value
(source)
449 (klacks:expecting-element
(source "value")
450 (let* ((type (ntc "type" source
))
451 (string (consume-and-parse-characters source
))
453 (dl *datatype-library
*))
457 (make-value :string string
:type type
:ns ns
:datatype-library dl
))))
459 (defun p/data
(source)
460 (klacks:expecting-element
(source "data")
461 (let* ((type (ntc "type" source
))
462 (result (make-data :type type
463 :datatype-library
*datatype-library
*
467 (multiple-value-bind (key uri lname
)
468 (klacks:peek-next source
)
472 (case (find-symbol lname
:keyword
)
473 (:|param|
(push (p/param source
) params
))
475 (setf (pattern-except result
) (p/except-pattern source
))
476 (skip-to-native source
)
478 (t (skip-foreign source
))))
481 (setf (pattern-params result
) (nreverse params
))
484 (defun p/param
(source)
485 (klacks:expecting-element
(source "param")
486 (let ((name (ntc "name" source
))
487 (string (consume-and-parse-characters source
)))
488 (make-param :name name
:string string
))))
490 (defun p/except-pattern
(source)
491 (klacks:expecting-element
(source "except")
492 (with-library-and-ns (klacks:list-attributes source
)
493 (klacks:consume source
)
494 (choice-ify (p/pattern
+ source
)))))
496 (defun p/not-allowed
(source)
497 (klacks:expecting-element
(source "notAllowed")
498 (consume-and-skip-to-native source
)
501 (defun safe-parse-uri (source str
&optional base
)
502 (when (zerop (length str
))
503 (rng-error source
"missing URI"))
506 (puri:merge-uris str base
)
507 (puri:parse-uri str
))
508 (puri:uri-parse-error
()
509 (rng-error source
"invalid URI: ~A" str
))))
511 (defun p/external-ref
(source)
512 (klacks:expecting-element
(source "externalRef")
514 (escape-uri (attribute "href" (klacks:list-attributes source
))))
515 (base (klacks:current-xml-base source
))
516 (uri (safe-parse-uri source href base
)))
517 (when (find uri
*include-uri-stack
* :test
#'puri
:uri
=)
518 (rng-error source
"looping include"))
520 (let* ((*include-uri-stack
* (cons uri
*include-uri-stack
*))
522 (cxml::xstream-open-extid
* *entity-resolver
* nil uri
)))
523 (klacks:with-open-source
(source (cxml:make-source xstream
))
524 (invoke-with-klacks-handler
526 (klacks:find-event source
:start-element
)
527 (let ((*datatype-library
* ""))
530 (skip-foreign* source
)))))
532 (defun p/grammar
(source &optional grammar
)
533 (klacks:expecting-element
(source "grammar")
534 (consume-and-skip-to-native source
)
535 (let ((*grammar
* (or grammar
(make-grammar *grammar
*))))
536 (process-grammar-content* source
)
537 (unless (grammar-start *grammar
*)
538 (rng-error source
"no <start> in grammar"))
539 (check-pattern-definitions source
*grammar
*)
540 (defn-child (grammar-start *grammar
*)))))
542 (defvar *include-start
*)
543 (defvar *include-definitions
*)
545 (defun process-grammar-content* (source &key disallow-include
)
547 (multiple-value-bind (key uri lname
) (klacks:peek source
)
551 (with-library-and-ns (klacks:list-attributes source
)
552 (case (find-symbol lname
:keyword
)
553 (:|start|
(process-start source
))
554 (:|define|
(process-define source
))
555 (:|div|
(process-div source
))
557 (when disallow-include
558 (rng-error source
"nested include not permitted"))
559 (process-include source
))
561 (skip-foreign source
)))))
564 (klacks:consume source
)))
566 (defun process-start (source)
567 (klacks:expecting-element
(source "start")
568 (let* ((combine0 (ntc "combine" source
))
571 (find-symbol (string-upcase combine0
) :keyword
)))
574 (consume-and-skip-to-native source
)
576 (pdefinition (grammar-start *grammar
*)))
577 (skip-foreign* source
)
578 ;; fixme: shared code with process-define
580 (setf pdefinition
(make-definition :name
:start
:child nil
))
581 (setf (grammar-start *grammar
*) pdefinition
))
582 (when *include-body-p
*
583 (setf *include-start
* pdefinition
))
585 ((defn-child pdefinition
)
586 (ecase (defn-redefinition pdefinition
)
587 (:not-being-redefined
589 (defn-combine-method pdefinition
)
591 (defn-combine-method pdefinition
))))
592 (rng-error source
"conflicting combine values for <start>"))
594 (when (defn-head-p pdefinition
)
595 (rng-error source
"multiple definitions for <start>"))
596 (setf (defn-head-p pdefinition
) t
))
597 (unless (defn-combine-method pdefinition
)
598 (setf (defn-combine-method pdefinition
) combine
))
599 (setf (defn-child pdefinition
)
600 (case (defn-combine-method pdefinition
)
602 (make-choice (defn-child pdefinition
) child
))
604 (make-interleave (defn-child pdefinition
) child
)))))
605 (:being-redefined-and-no-original
606 (setf (defn-redefinition pdefinition
)
607 :being-redefined-and-original
))
608 (:being-redefined-and-original
)))
610 (setf (defn-child pdefinition
) child
)
611 (setf (defn-combine-method pdefinition
) combine
)
612 (setf (defn-head-p pdefinition
) (null combine
))
613 (setf (defn-redefinition pdefinition
) :not-being-redefined
))))))
615 (defun zip (constructor children
)
618 (rng-error nil
"empty choice?"))
619 ((null (cdr children
))
622 (destructuring-bind (a b
&rest rest
)
624 (zip constructor
(cons (funcall constructor a b
) rest
))))))
626 (defun choice-ify (children) (zip #'make-choice children
))
627 (defun groupify (children) (zip #'make-group children
))
628 (defun interleave-ify (children) (zip #'make-interleave children
))
630 (defun find-definition (name &optional
(grammar *grammar
*))
631 (gethash name
(grammar-definitions grammar
)))
633 (defun (setf find-definition
) (newval name
&optional
(grammar *grammar
*))
634 (setf (gethash name
(grammar-definitions grammar
)) newval
))
636 (defun process-define (source)
637 (klacks:expecting-element
(source "define")
638 (let* ((name (ntc "name" source
))
639 (combine0 (ntc "combine" source
))
640 (combine (when combine0
641 (find-symbol (string-upcase combine0
) :keyword
)))
644 (consume-and-skip-to-native source
)
645 (p/pattern
+ source
))))
646 (pdefinition (find-definition name
)))
648 (setf pdefinition
(make-definition :name name
:child nil
))
649 (setf (find-definition name
) pdefinition
))
650 (when *include-body-p
*
651 (push pdefinition
*include-definitions
*))
653 ((defn-child pdefinition
)
654 (case (defn-redefinition pdefinition
)
655 (:not-being-redefined
657 (defn-combine-method pdefinition
)
659 (defn-combine-method pdefinition
))))
660 (rng-error source
"conflicting combine values for ~A" name
))
662 (when (defn-head-p pdefinition
)
663 (rng-error source
"multiple definitions for ~A" name
))
664 (setf (defn-head-p pdefinition
) t
))
665 (unless (defn-combine-method pdefinition
)
666 (setf (defn-combine-method pdefinition
) combine
))
667 (setf (defn-child pdefinition
)
668 (case (defn-combine-method pdefinition
)
670 (make-choice (defn-child pdefinition
) child
))
672 (make-interleave (defn-child pdefinition
) child
)))))
673 (:being-redefined-and-no-original
674 (setf (defn-redefinition pdefinition
)
675 :being-redefined-and-original
))
676 (:being-redefined-and-original
)))
678 (setf (defn-child pdefinition
) child
)
679 (setf (defn-combine-method pdefinition
) combine
)
680 (setf (defn-head-p pdefinition
) (null combine
))
681 (setf (defn-redefinition pdefinition
) :not-being-redefined
))))))
683 (defun process-div (source)
684 (klacks:expecting-element
(source "div")
685 (consume-and-skip-to-native source
)
686 (process-grammar-content* source
)))
688 (defun reset-definition-for-include (defn)
689 (setf (defn-combine-method defn
) nil
)
690 (setf (defn-redefinition defn
) :being-redefined-and-no-original
)
691 (setf (defn-head-p defn
) nil
))
693 (defun restore-definition (defn original
)
694 (setf (defn-combine-method defn
) (defn-combine-method original
))
695 (setf (defn-redefinition defn
) (defn-redefinition original
))
696 (setf (defn-head-p defn
) (defn-head-p original
)))
698 (defun process-include (source)
699 (klacks:expecting-element
(source "include")
701 (escape-uri (attribute "href" (klacks:list-attributes source
))))
702 (base (klacks:current-xml-base source
))
703 (uri (safe-parse-uri source href base
))
704 (*include-start
* nil
)
705 (*include-definitions
* '()))
706 (consume-and-skip-to-native source
)
707 (let ((*include-body-p
* t
))
708 (process-grammar-content* source
:disallow-include t
))
710 (when *include-start
*
712 (copy-structure *include-start
*)
713 (reset-definition-for-include *include-start
*))))
716 for defn in
*include-definitions
*
719 (copy-structure defn
)
720 (reset-definition-for-include defn
)))))
721 (when (find uri
*include-uri-stack
* :test
#'puri
:uri
=)
722 (rng-error source
"looping include"))
723 (let* ((*include-uri-stack
* (cons uri
*include-uri-stack
*))
724 (xstream (cxml::xstream-open-extid
* *entity-resolver
* nil uri
)))
725 (klacks:with-open-source
(source (cxml:make-source xstream
))
726 (invoke-with-klacks-handler
728 (klacks:find-event source
:start-element
)
729 (let ((*datatype-library
* ""))
730 (p/grammar source
*grammar
*)))
732 (check-pattern-definitions source
*grammar
*)
734 (restore-definition *include-start
* tmp-start
))
735 (dolist (copy tmp-defns
)
736 (let ((defn (gethash (defn-name copy
)
737 (grammar-definitions *grammar
*))))
738 (restore-definition defn copy
)))
739 (defn-child (grammar-start *grammar
*)))))))
741 (defun check-pattern-definitions (source grammar
)
742 (when (eq (defn-redefinition (grammar-start grammar
))
743 :being-redefined-and-no-original
)
744 (rng-error source
"start not found in redefinition of grammar"))
745 (loop for defn being each hash-value in
(grammar-definitions grammar
) do
746 (when (eq (defn-redefinition defn
) :being-redefined-and-no-original
)
747 (rng-error source
"redefinition not found in grammar"))
748 (unless (defn-child defn
)
749 (rng-error source
"unresolved reference to ~A" (defn-name defn
)))))
751 (defvar *any-name-allowed-p
* t
)
752 (defvar *ns-name-allowed-p
* t
)
754 (defun destructure-name (source qname
)
755 (multiple-value-bind (uri lname
)
756 (klacks:decode-qname qname source
)
757 (setf uri
(or uri
*namespace-uri
*))
758 (when (and *attribute-namespace-p
*
759 (or (and (equal lname
"xmlns") (equal uri
""))
760 (equal uri
"http://www.w3.org/2000/xmlns")))
761 (rng-error source
"namespace attribute not permitted"))
762 (make-name uri lname
)))
764 (defun p/name-class
(source)
765 (klacks:expecting-element
(source)
766 (with-library-and-ns (klacks:list-attributes source
)
767 (case (find-symbol (klacks:current-lname source
) :keyword
)
769 (let ((qname (string-trim *whitespace
*
770 (consume-and-parse-characters source
))))
771 (destructure-name source qname
)))
773 (unless *any-name-allowed-p
*
774 (rng-error source
"anyname now permitted in except"))
775 (klacks:consume source
)
777 (let ((*any-name-allowed-p
* nil
))
778 (make-any-name (p/except-name-class? source
)))
779 (skip-to-native source
)))
781 (unless *ns-name-allowed-p
*
782 (rng-error source
"nsname now permitted in except"))
783 (let ((uri *namespace-uri
*)
784 (*any-name-allowed-p
* nil
)
785 (*ns-name-allowed-p
* nil
))
786 (when (and *attribute-namespace-p
*
787 (equal uri
"http://www.w3.org/2000/xmlns"))
788 (rng-error source
"namespace attribute not permitted"))
789 (klacks:consume source
)
791 (make-ns-name uri
(p/except-name-class? source
))
792 (skip-to-native source
))))
794 (klacks:consume source
)
795 (simplify-nc-choice (p/name-class
* source
)))
797 (rng-error source
"invalid child in except"))))))
799 (defun p/name-class
* (source)
802 (skip-to-native source
)
803 (case (klacks:peek source
)
804 (:start-element
(push (p/name-class source
) results
))
805 (:end-element
(return)))
806 (klacks:consume source
))
809 (defun p/except-name-class?
(source)
810 (skip-to-native source
)
811 (multiple-value-bind (key uri lname
)
814 (if (and (eq key
:start-element
)
815 (string= (find-symbol lname
:keyword
) "except"))
816 (p/except-name-class source
)
819 (defun p/except-name-class
(source)
820 (klacks:expecting-element
(source "except")
821 (with-library-and-ns (klacks:list-attributes source
)
822 (klacks:consume source
)
823 (let ((x (p/name-class
* source
)))
825 (simplify-nc-choice x
)
828 (defun escape-uri (string)
829 (with-output-to-string (out)
830 (loop for c across
(cxml::rod-to-utf8-string string
) do
831 (let ((code (char-code c
)))
832 ;; http://www.w3.org/TR/xlink/#link-locators
833 (if (or (>= code
127) (<= code
32) (find c
"<>\"{}|\\^`"))
834 (format out
"%~2,'0X" code
)
835 (write-char c out
))))))
840 (defvar *definitions-to-names
*)
841 (defvar *seen-names
*)
843 (defun serialization-name (defn)
844 (or (gethash defn
*definitions-to-names
*)
845 (setf (gethash defn
*definitions-to-names
*)
846 (let ((name (if (gethash (defn-name defn
) *seen-names
*)
849 (hash-table-count *seen-names
*))
851 (setf (gethash name
*seen-names
*) defn
)
854 (defun serialize-grammar (grammar sink
)
855 (cxml:with-xml-output sink
856 (let ((*definitions-to-names
* (make-hash-table))
857 (*seen-names
* (make-hash-table :test
'equal
)))
858 (cxml:with-element
"grammar"
859 (cxml:with-element
"start"
860 (serialize-pattern (parsed-grammar-pattern grammar
)))
861 (loop for defn being each hash-key in
*definitions-to-names
* do
862 (serialize-definition defn
))))))
864 (defun serialize-pattern (pattern)
867 (cxml:with-element
"element"
868 (serialize-name (pattern-name pattern
))
869 (serialize-pattern (pattern-child pattern
))))
871 (cxml:with-element
"attribute"
872 (serialize-name (pattern-name pattern
))
873 (serialize-pattern (pattern-child pattern
))))
878 (interleave "interleave")
880 (serialize-pattern (pattern-a pattern
))
881 (serialize-pattern (pattern-b pattern
))))
883 (cxml:with-element
"oneOrmore"
884 (serialize-pattern (pattern-child pattern
))))
886 (cxml:with-element
"list"
887 (serialize-pattern (pattern-child pattern
))))
889 (cxml:with-element
"ref"
890 (cxml:attribute
"name" (serialization-name (pattern-target pattern
)))))
892 (cxml:with-element
"empty"))
894 (cxml:with-element
"notAllowed"))
896 (cxml:with-element
"text"))
898 (cxml:with-element
"value"
899 (cxml:attribute
"datatype-library"
900 (pattern-datatype-library pattern
))
901 (cxml:attribute
"type" (pattern-type pattern
))
902 (cxml:attribute
"ns" (pattern-ns pattern
))
903 (cxml:text
(pattern-string pattern
))))
905 (cxml:with-element
"value"
906 (cxml:attribute
"datatype-library"
907 (pattern-datatype-library pattern
))
908 (cxml:attribute
"type" (pattern-type pattern
))
909 (dolist (param (pattern-params pattern
))
910 (cxml:with-element
"param"
911 (cxml:attribute
"name" (param-name param
))
912 (cxml:text
(param-string param
))))
913 (when (pattern-except pattern
)
914 (cxml:with-element
"except"
915 (serialize-pattern (pattern-except pattern
))))))))
917 (defun serialize-definition (defn)
918 (cxml:with-element
"define"
919 (cxml:attribute
"name" (serialization-name defn
))
920 (serialize-pattern (defn-child defn
))))
922 (defun serialize-name (name)
925 (cxml:with-element
"name"
926 (cxml:attribute
"ns" (name-uri name
))
927 (cxml:text
(name-lname name
))))
929 (cxml:with-element
"anyName"
930 (when (any-name-except name
)
931 (serialize-except-name (any-name-except name
)))))
933 (cxml:with-element
"anyName"
934 (cxml:attribute
"ns" (ns-name-uri name
))
935 (when (ns-name-except name
)
936 (serialize-except-name (ns-name-except name
)))))
938 (cxml:with-element
"choice"
939 (serialize-name (name-class-choice-a name
))
940 (serialize-name (name-class-choice-b name
))))))
942 (defun serialize-except-name (spec)
943 (cxml:with-element
"except"
944 (serialize-name (cdr spec
))))
950 ;;; Foreign attributes and elements are removed implicitly while parsing.
953 ;;; All character data is discarded while parsing (which can only be
954 ;;; whitespace after validation).
956 ;;; Whitespace in name, type, and combine attributes is stripped while
957 ;;; parsing. Ditto for <name/>.
959 ;;; 4.3. datatypeLibrary attribute
960 ;;; Escaping is done by p/pattern.
961 ;;; Attribute value defaulting is done using *datatype-library*; only
962 ;;; p/data and p/value record the computed value.
964 ;;; 4.4. type attribute of value element
967 ;;; 4.5. href attribute
968 ;;; Escaping is done by process-include and p/external-ref.
970 ;;; FIXME: Mime-type handling should be the job of the entity resolver,
971 ;;; but that requires xstream hacking.
973 ;;; 4.6. externalRef element
974 ;;; Done by p/external-ref.
976 ;;; 4.7. include element
977 ;;; Done by process-include.
979 ;;; 4.8. name attribute of element and attribute elements
980 ;;; `name' is stored as a slot, not a child. Done by p/element and
983 ;;; 4.9. ns attribute
984 ;;; done by p/name-class, p/value, p/element, p/attribute
987 ;;; done by p/name-class
989 ;;; 4.11. div element
990 ;;; Legen wir gar nicht erst an.
992 ;;; 4.12. 4.13 4.14 4.15
997 ;;; -- ausser der sache mit den datentypen
1000 ;;; Ueber die Grammar-und Definition Objekte, wie von James Clark
1003 ;;; Dabei werden keine Umbenennungen vorgenommen, weil Referenzierung
1004 ;;; durch Aufbei der Graphenstruktur zwischen ref und Definition
1005 ;;; erfolgt und Namen dann bereits aufgeloest sind. Wir benennen
1006 ;;; dafuer beim Serialisieren um.
1008 (defmethod check-recursion ((pattern element
) depth
)
1009 (check-recursion (pattern-child pattern
) (1+ depth
)))
1011 (defmethod check-recursion ((pattern ref
) depth
)
1012 (when (eql (pattern-crdepth pattern
) depth
)
1013 (rng-error nil
"infinite recursion in ~A"
1014 (defn-name (pattern-target pattern
))))
1015 (when (null (pattern-crdepth pattern
))
1016 (setf (pattern-crdepth pattern
) depth
)
1017 (check-recursion (defn-child (pattern-target pattern
)) depth
)
1018 (setf (pattern-crdepth pattern
) t
)))
1020 (defmethod check-recursion ((pattern %parent
) depth
)
1021 (check-recursion (pattern-child pattern
) depth
))
1023 (defmethod check-recursion ((pattern %combination
) depth
)
1024 (check-recursion (pattern-a pattern
) depth
)
1025 (check-recursion (pattern-b pattern
) depth
))
1027 (defmethod check-recursion ((pattern %leaf
) depth
)
1028 (declare (ignore depth
)))
1030 (defmethod check-recursion ((pattern data
) depth
)
1031 (when (pattern-except pattern
)
1032 (check-recursion (pattern-except pattern
) depth
)))
1039 (defmethod fold-not-allowed ((pattern element
))
1040 (setf (pattern-child pattern
) (fold-not-allowed (pattern-child pattern
)))
1043 (defmethod fold-not-allowed ((pattern %parent
))
1044 (setf (pattern-child pattern
) (fold-not-allowed (pattern-child pattern
)))
1045 (if (typep (pattern-child pattern
) 'not-allowed
)
1046 (pattern-child pattern
)
1051 (defmethod fold-not-allowed ((pattern %combination
))
1052 (setf (pattern-a pattern
) (fold-not-allowed (pattern-a pattern
)))
1053 (setf (pattern-b pattern
) (fold-not-allowed (pattern-b pattern
)))
1056 (defmethod fold-not-allowed ((pattern group
))
1059 ;; remove if any child is not allowed
1060 ((typep (pattern-a pattern
) 'not-allowed
) (pattern-a pattern
))
1061 ((typep (pattern-b pattern
) 'not-allowed
) (pattern-b pattern
))
1064 (defmethod fold-not-allowed ((pattern interleave
))
1067 ;; remove if any child is not allowed
1068 ((typep (pattern-a pattern
) 'not-allowed
) (pattern-a pattern
))
1069 ((typep (pattern-b pattern
) 'not-allowed
) (pattern-b pattern
))
1072 (defmethod fold-not-allowed ((pattern choice
))
1075 ;; if any child is not allowed, choose the other
1076 ((typep (pattern-a pattern
) 'not-allowed
) (pattern-b pattern
))
1077 ((typep (pattern-b pattern
) 'not-allowed
) (pattern-a pattern
))
1082 (defmethod fold-not-allowed ((pattern %leaf
))
1085 (defmethod fold-not-allowed ((pattern data
))
1086 (when (pattern-except pattern
)
1087 (setf (pattern-except pattern
) (fold-not-allowed (pattern-except pattern
)))
1088 (when (typep (pattern-except pattern
) 'not-allowed
)
1089 (setf (pattern-except pattern
) nil
)))
1094 (defmethod fold-not-allowed ((pattern ref
))
1102 (defmethod fold-empty ((pattern one-or-more
))
1104 (if (typep (pattern-child pattern
) 'empty
)
1105 (pattern-child pattern
)
1108 (defmethod fold-empty ((pattern %parent
))
1109 (setf (pattern-child pattern
) (fold-empty (pattern-child pattern
)))
1114 (defmethod fold-empty ((pattern %combination
))
1115 (setf (pattern-a pattern
) (fold-empty (pattern-a pattern
)))
1116 (setf (pattern-b pattern
) (fold-empty (pattern-b pattern
)))
1119 (defmethod fold-empty ((pattern group
))
1122 ;; if any child is empty, choose the other
1123 ((typep (pattern-a pattern
) 'empty
) (pattern-b pattern
))
1124 ((typep (pattern-b pattern
) 'empty
) (pattern-a pattern
))
1127 (defmethod fold-empty ((pattern interleave
))
1130 ;; if any child is empty, choose the other
1131 ((typep (pattern-a pattern
) 'empty
) (pattern-b pattern
))
1132 ((typep (pattern-b pattern
) 'empty
) (pattern-a pattern
))
1135 (defmethod fold-empty ((pattern choice
))
1137 (if (typep (pattern-b pattern
) 'empty
)
1139 ((typep (pattern-a pattern
) 'empty
)
1140 (pattern-a pattern
))
1142 (rotatef (pattern-a pattern
) (pattern-b pattern
))
1148 (defmethod fold-empty ((pattern %leaf
))
1151 (defmethod fold-empty ((pattern data
))
1152 (when (pattern-except pattern
)
1153 (setf (pattern-except pattern
) (fold-empty (pattern-except pattern
))))
1158 (defmethod fold-empty ((pattern ref
))