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
71 (:constructor make-parsed-grammar
(pattern definitions
)))
72 (pattern (missing) :type pattern
)
73 (definitions (missing) :type list
)
74 (interned-start nil
:type
(or null pattern
))
75 (registratur nil
:type
(or null hash-table
)))
77 (defmethod print-object ((object parsed-grammar
) stream
)
78 (print-unreadable-object (object stream
:type t
:identity t
)))
80 (defun invoke-with-klacks-handler (fn source
)
85 (cxml:xml-parse-error
(c)
86 (rng-error source
"Cannot parse schema: ~A" c
)))))
88 (defvar *validate-grammar
* t
)
89 (defparameter *relax-ng-grammar
* nil
)
91 (defun make-validating-source (input)
92 (let ((upstream (cxml:make-source input
)))
93 (if *validate-grammar
*
94 (klacks:make-tapping-source upstream
95 (make-validator *relax-ng-grammar
*))
98 (defun parse-relax-ng (input &key entity-resolver
)
99 (when *validate-grammar
*
100 (unless *relax-ng-grammar
*
101 (setf *relax-ng-grammar
*
102 (let* ((*validate-grammar
* nil
)
103 (d (slot-value (asdf:find-system
:cxml-rng
)
104 'asdf
::relative-pathname
)))
105 (parse-relax-ng (merge-pathnames "rng.rng" d
))))))
106 (klacks:with-open-source
(source (make-validating-source input
))
107 (invoke-with-klacks-handler
109 (klacks:find-event source
:start-element
)
110 (let* ((*datatype-library
* "")
112 (*entity-resolver
* entity-resolver
)
113 (*external-href-stack
* '())
114 (*include-uri-stack
* '())
115 (*grammar
* (make-grammar nil
))
116 (start (p/pattern source
)))
118 (rng-error nil
"empty grammar"))
119 (setf (grammar-start *grammar
*)
120 (make-definition :name
:start
:child start
))
121 (check-pattern-definitions source
*grammar
*)
122 (check-recursion start
0)
123 (multiple-value-bind (new-start defns
)
124 (finalize-definitions start
)
125 (setf start
(fold-not-allowed new-start
))
127 (setf (defn-child defn
) (fold-not-allowed (defn-child defn
))))
128 (setf start
(fold-empty start
))
130 (setf (defn-child defn
) (fold-empty (defn-child defn
)))))
131 (multiple-value-bind (new-start defns
)
132 (finalize-definitions start
)
133 (check-start-restrictions new-start
)
135 (check-restrictions (defn-child defn
)))
136 (make-parsed-grammar new-start defns
))))
140 ;;;; pattern structures
144 (defmethod print-object :around
((object pattern
) stream
)
146 (let ((*print-circle
* t
))
148 (print-unreadable-object (object stream
:type t
:identity t
))))
150 (defstruct (%parent
(:include pattern
) (:conc-name
"PATTERN-"))
153 (defstruct (%named-pattern
(:include %parent
) (:conc-name
"PATTERN-"))
155 (defstruct (element (:include %named-pattern
) (:conc-name
"PATTERN-")))
156 (defstruct (attribute (:include %named-pattern
) (:conc-name
"PATTERN-")))
158 (defstruct (%combination
(:include pattern
) (:conc-name
"PATTERN-"))
161 (:include %combination
)
162 (:constructor make-group
(a b
))))
163 (defstruct (interleave
164 (:include %combination
)
165 (:constructor make-interleave
(a b
))))
167 (:include %combination
)
168 (:constructor make-choice
(a b
))))
170 (:include %combination
)
171 (:constructor make-after
(a b
))))
173 (defstruct (one-or-more
175 (:constructor make-one-or-more
(child))))
176 (defstruct (list-pattern
178 (:constructor make-list-pattern
(child))))
182 (:conc-name
"PATTERN-")
183 (:constructor make-ref
(target)))
187 (defstruct (%leaf
(:include pattern
)))
189 (defstruct (empty (:include %leaf
) (:conc-name
"PATTERN-")))
190 (defstruct (text (:include %leaf
) (:conc-name
"PATTERN-")))
192 (defstruct (%typed-pattern
(:include %leaf
) (:conc-name
"PATTERN-"))
195 (defstruct (value (:include %typed-pattern
) (:conc-name
"PATTERN-"))
200 (defstruct (data (:include %typed-pattern
) (:conc-name
"PATTERN-"))
204 (defstruct (not-allowed (:include %leaf
) (:conc-name
"PATTERN-")))
209 (defstruct (grammar (:constructor make-grammar
(parent)))
212 (definitions (make-hash-table :test
'equal
)))
218 ;; Clark calls this structure "RefPattern"
219 (defstruct (definition (:conc-name
"DEFN-"))
230 (error "missing arg"))
232 (defstruct name-class
)
234 (defstruct (any-name (:include name-class
)
235 (:constructor make-any-name
(except)))
236 (except (missing) :type
(or null name-class
)))
238 (defstruct (name (:include name-class
)
239 (:constructor make-name
(uri lname
)))
240 (uri (missing) :type string
)
241 (lname (missing) :type string
))
243 (defstruct (ns-name (:include name-class
)
244 (:constructor make-ns-name
(uri except
)))
245 (uri (missing) :type string
)
246 (except (missing) :type
(or null name-class
)))
248 (defstruct (name-class-choice (:include name-class
)
249 (:constructor make-name-class-choice
(a b
)))
250 (a (missing) :type name-class
)
251 (b (missing) :type name-class
))
253 (defun simplify-nc-choice (values)
254 (zip #'make-name-class-choice values
))
259 (defvar *rng-namespace
* "http://relaxng.org/ns/structure/1.0")
261 (defun skip-foreign* (source)
263 (case (klacks:peek-next source
)
264 (:start-element
(skip-foreign source
))
265 (:end-element
(return)))))
267 (defun skip-to-native (source)
269 (case (klacks:peek source
)
271 (when (equal (klacks:current-uri source
) *rng-namespace
*)
273 (klacks:serialize-element source nil
))
274 (:end-element
(return)))
275 (klacks:consume source
)))
277 (defun consume-and-skip-to-native (source)
278 (klacks:consume source
)
279 (skip-to-native source
))
281 (defun skip-foreign (source)
282 (when (equal (klacks:current-uri source
) *rng-namespace
*)
284 "invalid schema: ~A not allowed here"
285 (klacks:current-lname source
)))
286 (klacks:serialize-element source nil
))
288 (defun attribute (lname attrs
)
289 (let ((a (sax:find-attribute-ns
"" lname attrs
)))
291 (sax:attribute-value a
)
294 (defparameter *whitespace
*
295 (format nil
"~C~C~C~C"
301 (defun ntc (lname source-or-attrs
)
302 ;; used for (n)ame, (t)ype, and (c)ombine, this also strings whitespace
304 (if (listp source-or-attrs
)
306 (klacks:list-attributes source-or-attrs
)))
307 (a (sax:find-attribute-ns
"" lname attrs
)))
309 (string-trim *whitespace
* (sax:attribute-value a
))
312 (defmacro with-library-and-ns
(attrs &body body
)
313 `(invoke-with-library-and-ns (lambda () ,@body
) ,attrs
))
315 (defun invoke-with-library-and-ns (fn attrs
)
316 (let* ((dl (attribute "datatypeLibrary" attrs
))
317 (ns (attribute "ns" attrs
))
318 (*datatype-library
* (if dl
(escape-uri dl
) *datatype-library
*))
319 (*namespace-uri
* (or ns
*namespace-uri
*))
323 (defun p/pattern
(source)
324 (let* ((lname (klacks:current-lname source
))
325 (attrs (klacks:list-attributes source
)))
326 (with-library-and-ns attrs
327 (case (find-symbol lname
:keyword
)
328 (:|element|
(p/element source
(ntc "name" attrs
)))
329 (:|attribute|
(p/attribute source
(ntc "name" attrs
)))
330 (:|group|
(p/combination
#'groupify source
))
331 (:|interleave|
(p/combination
#'interleave-ify source
))
332 (:|choice|
(p/combination
#'choice-ify source
))
333 (:|optional|
(p/optional source
))
334 (:|zeroOrMore|
(p/zero-or-more source
))
335 (:|oneOrMore|
(p/one-or-more source
))
336 (:|list|
(p/list source
))
337 (:|mixed|
(p/mixed source
))
338 (:|ref|
(p/ref source
))
339 (:|parentRef|
(p/parent-ref source
))
340 (:|empty|
(p/empty source
))
341 (:|text|
(p/text source
))
342 (:|value|
(p/value source
))
343 (:|data|
(p/data source
))
344 (:|notAllowed|
(p/not-allowed source
))
345 (:|externalRef|
(p/external-ref source
))
346 (:|grammar|
(p/grammar source
))
347 (t (skip-foreign source
))))))
349 (defun p/pattern
+ (source)
350 (let ((children nil
))
352 (case (klacks:peek source
)
354 (let ((p (p/pattern source
))) (when p
(push p children
))))
358 (klacks:consume source
))))
360 (rng-error source
"empty element"))
361 (nreverse children
)))
363 (defun p/pattern?
(source)
366 (skip-to-native source
)
367 (case (klacks:peek source
)
370 (rng-error source
"at most one pattern expected here"))
371 (setf result
(p/pattern source
)))
375 (klacks:consume source
))))
378 (defun p/element
(source name
)
379 (klacks:expecting-element
(source "element")
380 (let ((elt (make-element)))
381 (consume-and-skip-to-native source
)
383 (setf (pattern-name elt
) (destructure-name source name
))
384 (setf (pattern-name elt
) (p/name-class source
)))
385 (skip-to-native source
)
386 (setf (pattern-child elt
) (groupify (p/pattern
+ source
)))
387 (make-ref (make-definition :name
(gensym "ANONYMOUS") :child elt
)))))
389 (defvar *attribute-namespace-p
* nil
)
391 (defun p/attribute
(source name
)
392 (klacks:expecting-element
(source "attribute")
393 (let ((result (make-attribute)))
394 (consume-and-skip-to-native source
)
396 (setf (pattern-name result
)
397 (let ((*namespace-uri
* (or *ns
* "")))
398 (destructure-name source name
)))
399 (setf (pattern-name result
)
400 (let ((*attribute-namespace-p
* t
))
401 (p/name-class source
))))
402 (skip-to-native source
)
403 (setf (pattern-child result
)
404 (or (p/pattern? source
) (make-text)))
407 (defun p/combination
(zipper source
)
408 (klacks:expecting-element
(source)
409 (consume-and-skip-to-native source
)
410 (funcall zipper
(p/pattern
+ source
))))
412 (defun p/one-or-more
(source)
413 (klacks:expecting-element
(source "oneOrMore")
414 (consume-and-skip-to-native source
)
415 (let ((children (p/pattern
+ source
)))
416 (make-one-or-more (groupify children
)))))
418 (defun p/zero-or-more
(source)
419 (klacks:expecting-element
(source "zeroOrMore")
420 (consume-and-skip-to-native source
)
421 (let ((children (p/pattern
+ source
)))
422 (make-choice (make-one-or-more (groupify children
))
425 (defun p/optional
(source)
426 (klacks:expecting-element
(source "optional")
427 (consume-and-skip-to-native source
)
428 (let ((children (p/pattern
+ source
)))
429 (make-choice (groupify children
) (make-empty)))))
431 (defun p/list
(source)
432 (klacks:expecting-element
(source "list")
433 (consume-and-skip-to-native source
)
434 (let ((children (p/pattern
+ source
)))
435 (make-list-pattern (groupify children
)))))
437 (defun p/mixed
(source)
438 (klacks:expecting-element
(source "mixed")
439 (consume-and-skip-to-native source
)
440 (let ((children (p/pattern
+ source
)))
441 (make-interleave (groupify children
) (make-text)))))
443 (defun p/ref
(source)
444 (klacks:expecting-element
(source "ref")
446 (let* ((name (ntc "name" source
))
448 (or (find-definition name
)
449 (setf (find-definition name
)
450 (make-definition :name name
:child nil
)))))
451 (make-ref pdefinition
))
452 (skip-foreign* source
))))
454 (defun p/parent-ref
(source)
455 (klacks:expecting-element
(source "parentRef")
457 (let* ((name (ntc "name" source
))
458 (grammar (grammar-parent *grammar
*))
460 (or (find-definition name grammar
)
461 (setf (find-definition name grammar
)
462 (make-definition :name name
:child nil
)))))
463 (make-ref pdefinition
))
464 (skip-foreign* source
))))
466 (defun p/empty
(source)
467 (klacks:expecting-element
(source "empty")
468 (skip-foreign* source
)
471 (defun p/text
(source)
472 (klacks:expecting-element
(source "text")
473 (skip-foreign* source
)
476 (defun consume-and-parse-characters (source)
480 (multiple-value-bind (key data
) (klacks:peek-next source
)
483 (setf tmp
(concatenate 'string tmp data
)))
484 (:end-element
(return)))))
487 (defun p/value
(source)
488 (klacks:expecting-element
(source "value")
489 (let* ((type (ntc "type" source
))
490 (string (consume-and-parse-characters source
))
492 (dl *datatype-library
*))
497 (cxml-types:find-type
(and dl
(find-symbol dl
:keyword
)) type
))
498 (vc (cxml-types:make-klacks-validation-context source
)))
500 (rng-error source
"type not found: ~A/~A" type dl
))
501 (make-value :string string
502 :value
(cxml-types:parse data-type string vc
)
506 (defun p/data
(source)
507 (klacks:expecting-element
(source "data")
508 (let* ((type (ntc "type" source
))
512 (multiple-value-bind (key uri lname
)
513 (klacks:peek-next source
)
517 (case (find-symbol lname
:keyword
)
518 (:|param|
(push (p/param source
) params
))
520 (setf except
(p/except-pattern source
))
521 (skip-to-native source
)
523 (t (skip-foreign source
))))
526 (setf params
(nreverse params
))
527 (let* ((dl *datatype-library
*)
528 (data-type (apply #'cxml-types
:find-type
529 (and dl
(find-symbol dl
:keyword
))
533 collect
(find-symbol (param-name p
)
535 collect
(param-string p
)))))
537 (rng-error source
"type not found: ~A/~A" type dl
))
543 (defun p/param
(source)
544 (klacks:expecting-element
(source "param")
545 (let ((name (ntc "name" source
))
546 (string (consume-and-parse-characters source
)))
547 (make-param :name name
:string string
))))
549 (defun p/except-pattern
(source)
550 (klacks:expecting-element
(source "except")
551 (with-library-and-ns (klacks:list-attributes source
)
552 (klacks:consume source
)
553 (choice-ify (p/pattern
+ source
)))))
555 (defun p/not-allowed
(source)
556 (klacks:expecting-element
(source "notAllowed")
557 (consume-and-skip-to-native source
)
560 (defun safe-parse-uri (source str
&optional base
)
561 (when (zerop (length str
))
562 (rng-error source
"missing URI"))
565 (puri:merge-uris str base
)
566 (puri:parse-uri str
))
567 (puri:uri-parse-error
()
568 (rng-error source
"invalid URI: ~A" str
))))
570 (defun p/external-ref
(source)
571 (klacks:expecting-element
(source "externalRef")
573 (escape-uri (attribute "href" (klacks:list-attributes source
))))
574 (base (klacks:current-xml-base source
))
575 (uri (safe-parse-uri source href base
)))
576 (when (find uri
*include-uri-stack
* :test
#'puri
:uri
=)
577 (rng-error source
"looping include"))
579 (let* ((*include-uri-stack
* (cons uri
*include-uri-stack
*))
581 (cxml::xstream-open-extid
* *entity-resolver
* nil uri
)))
582 (klacks:with-open-source
(source (make-validating-source xstream
))
583 (invoke-with-klacks-handler
585 (klacks:find-event source
:start-element
)
586 (let ((*datatype-library
* ""))
589 (skip-foreign* source
)))))
591 (defun p/grammar
(source &optional grammar
)
592 (klacks:expecting-element
(source "grammar")
593 (consume-and-skip-to-native source
)
594 (let ((*grammar
* (or grammar
(make-grammar *grammar
*)))
596 (process-grammar-content* source
)
597 (unless (or includep
(grammar-start *grammar
*))
598 (rng-error source
"no <start> in grammar"))
600 (check-pattern-definitions source
*grammar
*)
601 (defn-child (grammar-start *grammar
*))))))
603 (defvar *include-start
*)
604 (defvar *include-definitions
*)
606 (defun process-grammar-content* (source &key disallow-include
)
608 (multiple-value-bind (key uri lname
) (klacks:peek source
)
612 (with-library-and-ns (klacks:list-attributes source
)
613 (case (find-symbol lname
:keyword
)
614 (:|start|
(process-start source
))
615 (:|define|
(process-define source
))
616 (:|div|
(process-div source
))
618 (when disallow-include
619 (rng-error source
"nested include not permitted"))
620 (process-include source
))
622 (skip-foreign source
)))))
625 (klacks:consume source
)))
627 (defun process-start (source)
628 (klacks:expecting-element
(source "start")
629 (let* ((combine0 (ntc "combine" source
))
632 (find-symbol (string-upcase combine0
) :keyword
)))
635 (consume-and-skip-to-native source
)
637 (pdefinition (grammar-start *grammar
*)))
638 (skip-foreign* source
)
639 ;; fixme: shared code with process-define
641 (setf pdefinition
(make-definition :name
:start
:child nil
))
642 (setf (grammar-start *grammar
*) pdefinition
))
643 (when *include-body-p
*
644 (setf *include-start
* pdefinition
))
646 ((defn-child pdefinition
)
647 (ecase (defn-redefinition pdefinition
)
648 (:not-being-redefined
650 (defn-combine-method pdefinition
)
652 (defn-combine-method pdefinition
))))
653 (rng-error source
"conflicting combine values for <start>"))
655 (when (defn-head-p pdefinition
)
656 (rng-error source
"multiple definitions for <start>"))
657 (setf (defn-head-p pdefinition
) t
))
658 (unless (defn-combine-method pdefinition
)
659 (setf (defn-combine-method pdefinition
) combine
))
660 (setf (defn-child pdefinition
)
661 (case (defn-combine-method pdefinition
)
663 (make-choice (defn-child pdefinition
) child
))
665 (make-interleave (defn-child pdefinition
) child
)))))
666 (:being-redefined-and-no-original
667 (setf (defn-redefinition pdefinition
)
668 :being-redefined-and-original
))
669 (:being-redefined-and-original
)))
671 (setf (defn-child pdefinition
) child
)
672 (setf (defn-combine-method pdefinition
) combine
)
673 (setf (defn-head-p pdefinition
) (null combine
))
674 (setf (defn-redefinition pdefinition
) :not-being-redefined
))))))
676 (defun zip (constructor children
)
679 (rng-error nil
"empty choice?"))
680 ((null (cdr children
))
683 (destructuring-bind (a b
&rest rest
)
685 (zip constructor
(cons (funcall constructor a b
) rest
))))))
687 (defun choice-ify (children) (zip #'make-choice children
))
688 (defun groupify (children) (zip #'make-group children
))
689 (defun interleave-ify (children) (zip #'make-interleave children
))
691 (defun find-definition (name &optional
(grammar *grammar
*))
692 (gethash name
(grammar-definitions grammar
)))
694 (defun (setf find-definition
) (newval name
&optional
(grammar *grammar
*))
695 (setf (gethash name
(grammar-definitions grammar
)) newval
))
697 (defun process-define (source)
698 (klacks:expecting-element
(source "define")
699 (let* ((name (ntc "name" source
))
700 (combine0 (ntc "combine" source
))
701 (combine (when combine0
702 (find-symbol (string-upcase combine0
) :keyword
)))
705 (consume-and-skip-to-native source
)
706 (p/pattern
+ source
))))
707 (pdefinition (find-definition name
)))
709 (setf pdefinition
(make-definition :name name
:child nil
))
710 (setf (find-definition name
) pdefinition
))
711 (when *include-body-p
*
712 (push pdefinition
*include-definitions
*))
714 ((defn-child pdefinition
)
715 (case (defn-redefinition pdefinition
)
716 (:not-being-redefined
718 (defn-combine-method pdefinition
)
720 (defn-combine-method pdefinition
))))
721 (rng-error source
"conflicting combine values for ~A" name
))
723 (when (defn-head-p pdefinition
)
724 (rng-error source
"multiple definitions for ~A" name
))
725 (setf (defn-head-p pdefinition
) t
))
726 (unless (defn-combine-method pdefinition
)
727 (setf (defn-combine-method pdefinition
) combine
))
728 (setf (defn-child pdefinition
)
729 (case (defn-combine-method pdefinition
)
731 (make-choice (defn-child pdefinition
) child
))
733 (make-interleave (defn-child pdefinition
) child
)))))
734 (:being-redefined-and-no-original
735 (setf (defn-redefinition pdefinition
)
736 :being-redefined-and-original
))
737 (:being-redefined-and-original
)))
739 (setf (defn-child pdefinition
) child
)
740 (setf (defn-combine-method pdefinition
) combine
)
741 (setf (defn-head-p pdefinition
) (null combine
))
742 (setf (defn-redefinition pdefinition
) :not-being-redefined
))))))
744 (defun process-div (source)
745 (klacks:expecting-element
(source "div")
746 (consume-and-skip-to-native source
)
747 (process-grammar-content* source
)))
749 (defun reset-definition-for-include (defn)
750 (setf (defn-combine-method defn
) nil
)
751 (setf (defn-redefinition defn
) :being-redefined-and-no-original
)
752 (setf (defn-head-p defn
) nil
))
754 (defun restore-definition (defn original
)
755 (setf (defn-combine-method defn
) (defn-combine-method original
))
756 (setf (defn-redefinition defn
) (defn-redefinition original
))
757 (setf (defn-head-p defn
) (defn-head-p original
)))
759 (defun process-include (source)
760 (klacks:expecting-element
(source "include")
762 (escape-uri (attribute "href" (klacks:list-attributes source
))))
763 (base (klacks:current-xml-base source
))
764 (uri (safe-parse-uri source href base
))
765 (*include-start
* nil
)
766 (*include-definitions
* '()))
767 (consume-and-skip-to-native source
)
768 (let ((*include-body-p
* t
))
769 (process-grammar-content* source
:disallow-include t
))
771 (when *include-start
*
773 (copy-structure *include-start
*)
774 (reset-definition-for-include *include-start
*))))
777 for defn in
*include-definitions
*
780 (copy-structure defn
)
781 (reset-definition-for-include defn
)))))
782 (when (find uri
*include-uri-stack
* :test
#'puri
:uri
=)
783 (rng-error source
"looping include"))
784 (let* ((*include-uri-stack
* (cons uri
*include-uri-stack
*))
785 (xstream (cxml::xstream-open-extid
* *entity-resolver
* nil uri
)))
786 (klacks:with-open-source
(source (make-validating-source xstream
))
787 (invoke-with-klacks-handler
789 (klacks:find-event source
:start-element
)
790 (let ((*datatype-library
* ""))
791 (p/grammar source
*grammar
*)))
794 (when (eq (defn-redefinition *include-start
*)
795 :being-redefined-and-no-original
)
796 (rng-error source
"start not found in redefinition of grammar"))
797 (restore-definition *include-start
* tmp-start
))
798 (dolist (copy tmp-defns
)
799 (let ((defn (gethash (defn-name copy
)
800 (grammar-definitions *grammar
*))))
801 (when (eq (defn-redefinition defn
)
802 :being-redefined-and-no-original
)
803 (rng-error source
"redefinition not found in grammar"))
804 (restore-definition defn copy
)))
807 (defun check-pattern-definitions (source grammar
)
808 (when (and (grammar-start grammar
)
809 (eq (defn-redefinition (grammar-start grammar
))
810 :being-redefined-and-no-original
))
811 (rng-error source
"start not found in redefinition of grammar"))
812 (loop for defn being each hash-value in
(grammar-definitions grammar
) do
813 (when (eq (defn-redefinition defn
) :being-redefined-and-no-original
)
814 (rng-error source
"redefinition not found in grammar"))
815 (unless (defn-child defn
)
816 (rng-error source
"unresolved reference to ~A" (defn-name defn
)))))
818 (defvar *any-name-allowed-p
* t
)
819 (defvar *ns-name-allowed-p
* t
)
821 (defun destructure-name (source qname
)
822 (multiple-value-bind (uri lname
)
823 (klacks:decode-qname qname source
)
824 (setf uri
(or uri
*namespace-uri
*))
825 (when (and *attribute-namespace-p
*
826 (or (and (equal lname
"xmlns") (equal uri
""))
827 (equal uri
"http://www.w3.org/2000/xmlns")))
828 (rng-error source
"namespace attribute not permitted"))
829 (make-name uri lname
)))
831 (defun p/name-class
(source)
832 (klacks:expecting-element
(source)
833 (with-library-and-ns (klacks:list-attributes source
)
834 (case (find-symbol (klacks:current-lname source
) :keyword
)
836 (let ((qname (string-trim *whitespace
*
837 (consume-and-parse-characters source
))))
838 (destructure-name source qname
)))
840 (unless *any-name-allowed-p
*
841 (rng-error source
"anyname now permitted in except"))
842 (klacks:consume source
)
844 (let ((*any-name-allowed-p
* nil
))
845 (make-any-name (p/except-name-class? source
)))
846 (skip-to-native source
)))
848 (unless *ns-name-allowed-p
*
849 (rng-error source
"nsname now permitted in except"))
850 (let ((uri *namespace-uri
*)
851 (*any-name-allowed-p
* nil
)
852 (*ns-name-allowed-p
* nil
))
853 (when (and *attribute-namespace-p
*
854 (equal uri
"http://www.w3.org/2000/xmlns"))
855 (rng-error source
"namespace attribute not permitted"))
856 (klacks:consume source
)
858 (make-ns-name uri
(p/except-name-class? source
))
859 (skip-to-native source
))))
861 (klacks:consume source
)
862 (simplify-nc-choice (p/name-class
* source
)))
864 (rng-error source
"invalid child in except"))))))
866 (defun p/name-class
* (source)
869 (skip-to-native source
)
870 (case (klacks:peek source
)
871 (:start-element
(push (p/name-class source
) results
))
872 (:end-element
(return)))
873 (klacks:consume source
))
876 (defun p/except-name-class?
(source)
877 (skip-to-native source
)
878 (multiple-value-bind (key uri lname
)
881 (if (and (eq key
:start-element
)
882 (string= (find-symbol lname
:keyword
) "except"))
883 (p/except-name-class source
)
886 (defun p/except-name-class
(source)
887 (klacks:expecting-element
(source "except")
888 (with-library-and-ns (klacks:list-attributes source
)
889 (klacks:consume source
)
890 (let ((x (p/name-class
* source
)))
892 (simplify-nc-choice x
)
895 (defun escape-uri (string)
896 (with-output-to-string (out)
897 (loop for c across
(cxml::rod-to-utf8-string string
) do
898 (let ((code (char-code c
)))
899 ;; http://www.w3.org/TR/xlink/#link-locators
900 (if (or (>= code
127) (<= code
32) (find c
"<>\"{}|\\^`"))
901 (format out
"%~2,'0X" code
)
902 (write-char c out
))))))
907 (defvar *definitions-to-names
*)
908 (defvar *seen-names
*)
910 (defun serialization-name (defn)
911 (or (gethash defn
*definitions-to-names
*)
912 (setf (gethash defn
*definitions-to-names
*)
913 (let ((name (if (gethash (defn-name defn
) *seen-names
*)
916 (hash-table-count *seen-names
*))
918 (setf (gethash name
*seen-names
*) defn
)
921 (defun serialize-grammar (grammar sink
)
922 (cxml:with-xml-output sink
923 (let ((*definitions-to-names
* (make-hash-table))
924 (*seen-names
* (make-hash-table :test
'equal
)))
925 (cxml:with-element
"grammar"
926 (cxml:with-element
"start"
927 (serialize-pattern (parsed-grammar-pattern grammar
)))
928 (loop for defn being each hash-key in
*definitions-to-names
* do
929 (serialize-definition defn
))))))
931 (defun serialize-pattern (pattern)
934 (cxml:with-element
"element"
935 (serialize-name (pattern-name pattern
))
936 (serialize-pattern (pattern-child pattern
))))
938 (cxml:with-element
"attribute"
939 (serialize-name (pattern-name pattern
))
940 (serialize-pattern (pattern-child pattern
))))
945 (interleave "interleave")
947 (serialize-pattern (pattern-a pattern
))
948 (serialize-pattern (pattern-b pattern
))))
950 (cxml:with-element
"oneOrMore"
951 (serialize-pattern (pattern-child pattern
))))
953 (cxml:with-element
"list"
954 (serialize-pattern (pattern-child pattern
))))
956 (cxml:with-element
"ref"
957 (cxml:attribute
"name" (serialization-name (pattern-target pattern
)))))
959 (cxml:with-element
"empty"))
961 (cxml:with-element
"notAllowed"))
963 (cxml:with-element
"text"))
965 (cxml:with-element
"value"
966 (let ((type (pattern-type pattern
)))
967 (cxml:attribute
"datatype-library"
968 (symbol-name (cxml-types:type-library type
)))
969 (cxml:attribute
"type" (cxml-types:type-name type
)))
970 (cxml:attribute
"ns" (pattern-ns pattern
))
971 (cxml:text
(pattern-string pattern
))))
973 (cxml:with-element
"value"
974 (let ((type (pattern-type pattern
)))
975 (cxml:attribute
"datatype-library"
976 (symbol-name (cxml-types:type-library type
)))
977 (cxml:attribute
"type" (cxml-types:type-name type
)))
978 (dolist (param (pattern-params pattern
))
979 (cxml:with-element
"param"
980 (cxml:attribute
"name" (param-name param
))
981 (cxml:text
(param-string param
))))
982 (when (pattern-except pattern
)
983 (cxml:with-element
"except"
984 (serialize-pattern (pattern-except pattern
))))))))
986 (defun serialize-definition (defn)
987 (cxml:with-element
"define"
988 (cxml:attribute
"name" (serialization-name defn
))
989 (serialize-pattern (defn-child defn
))))
991 (defun serialize-name (name)
994 (cxml:with-element
"name"
995 (cxml:attribute
"ns" (name-uri name
))
996 (cxml:text
(name-lname name
))))
998 (cxml:with-element
"anyName"
999 (when (any-name-except name
)
1000 (serialize-except-name (any-name-except name
)))))
1002 (cxml:with-element
"anyName"
1003 (cxml:attribute
"ns" (ns-name-uri name
))
1004 (when (ns-name-except name
)
1005 (serialize-except-name (ns-name-except name
)))))
1007 (cxml:with-element
"choice"
1008 (serialize-name (name-class-choice-a name
))
1009 (serialize-name (name-class-choice-b name
))))))
1011 (defun serialize-except-name (spec)
1012 (cxml:with-element
"except"
1013 (serialize-name spec
)))
1019 ;;; Foreign attributes and elements are removed implicitly while parsing.
1022 ;;; All character data is discarded while parsing (which can only be
1023 ;;; whitespace after validation).
1025 ;;; Whitespace in name, type, and combine attributes is stripped while
1026 ;;; parsing. Ditto for <name/>.
1028 ;;; 4.3. datatypeLibrary attribute
1029 ;;; Escaping is done by p/pattern.
1030 ;;; Attribute value defaulting is done using *datatype-library*; only
1031 ;;; p/data and p/value record the computed value.
1033 ;;; 4.4. type attribute of value element
1034 ;;; Done by p/value.
1036 ;;; 4.5. href attribute
1037 ;;; Escaping is done by process-include and p/external-ref.
1039 ;;; FIXME: Mime-type handling should be the job of the entity resolver,
1040 ;;; but that requires xstream hacking.
1042 ;;; 4.6. externalRef element
1043 ;;; Done by p/external-ref.
1045 ;;; 4.7. include element
1046 ;;; Done by process-include.
1048 ;;; 4.8. name attribute of element and attribute elements
1049 ;;; `name' is stored as a slot, not a child. Done by p/element and
1052 ;;; 4.9. ns attribute
1053 ;;; done by p/name-class, p/value, p/element, p/attribute
1056 ;;; done by p/name-class
1058 ;;; 4.11. div element
1059 ;;; Legen wir gar nicht erst an.
1061 ;;; 4.12. 4.13 4.14 4.15
1066 ;;; -- ausser der sache mit den datentypen
1068 ;;; 4.17, 4.18, 4.19
1069 ;;; Ueber die Grammar-und Definition Objekte, wie von James Clark
1072 ;;; Dabei werden keine Umbenennungen vorgenommen, weil Referenzierung
1073 ;;; durch Aufbei der Graphenstruktur zwischen ref und Definition
1074 ;;; erfolgt und Namen dann bereits aufgeloest sind. Wir benennen
1075 ;;; dafuer beim Serialisieren um.
1077 (defmethod check-recursion ((pattern element
) depth
)
1078 (check-recursion (pattern-child pattern
) (1+ depth
)))
1080 (defmethod check-recursion ((pattern ref
) depth
)
1081 (when (eql (pattern-crdepth pattern
) depth
)
1082 (rng-error nil
"infinite recursion in ~A"
1083 (defn-name (pattern-target pattern
))))
1084 (when (null (pattern-crdepth pattern
))
1085 (setf (pattern-crdepth pattern
) depth
)
1086 (check-recursion (defn-child (pattern-target pattern
)) depth
)
1087 (setf (pattern-crdepth pattern
) t
)))
1089 (defmethod check-recursion ((pattern %parent
) depth
)
1090 (check-recursion (pattern-child pattern
) depth
))
1092 (defmethod check-recursion ((pattern %combination
) depth
)
1093 (check-recursion (pattern-a pattern
) depth
)
1094 (check-recursion (pattern-b pattern
) depth
))
1096 (defmethod check-recursion ((pattern %leaf
) depth
)
1097 (declare (ignore depth
)))
1099 (defmethod check-recursion ((pattern data
) depth
)
1100 (when (pattern-except pattern
)
1101 (check-recursion (pattern-except pattern
) depth
)))
1108 (defmethod fold-not-allowed ((pattern element
))
1109 (setf (pattern-child pattern
) (fold-not-allowed (pattern-child pattern
)))
1112 (defmethod fold-not-allowed ((pattern %parent
))
1113 (setf (pattern-child pattern
) (fold-not-allowed (pattern-child pattern
)))
1114 (if (typep (pattern-child pattern
) 'not-allowed
)
1115 (pattern-child pattern
)
1120 (defmethod fold-not-allowed ((pattern %combination
))
1121 (setf (pattern-a pattern
) (fold-not-allowed (pattern-a pattern
)))
1122 (setf (pattern-b pattern
) (fold-not-allowed (pattern-b pattern
)))
1125 (defmethod fold-not-allowed ((pattern group
))
1128 ;; remove if any child is not allowed
1129 ((typep (pattern-a pattern
) 'not-allowed
) (pattern-a pattern
))
1130 ((typep (pattern-b pattern
) 'not-allowed
) (pattern-b pattern
))
1133 (defmethod fold-not-allowed ((pattern interleave
))
1136 ;; remove if any child is not allowed
1137 ((typep (pattern-a pattern
) 'not-allowed
) (pattern-a pattern
))
1138 ((typep (pattern-b pattern
) 'not-allowed
) (pattern-b pattern
))
1141 (defmethod fold-not-allowed ((pattern choice
))
1144 ;; if any child is not allowed, choose the other
1145 ((typep (pattern-a pattern
) 'not-allowed
) (pattern-b pattern
))
1146 ((typep (pattern-b pattern
) 'not-allowed
) (pattern-a pattern
))
1151 (defmethod fold-not-allowed ((pattern %leaf
))
1154 (defmethod fold-not-allowed ((pattern data
))
1155 (when (pattern-except pattern
)
1156 (setf (pattern-except pattern
) (fold-not-allowed (pattern-except pattern
)))
1157 (when (typep (pattern-except pattern
) 'not-allowed
)
1158 (setf (pattern-except pattern
) nil
)))
1163 (defmethod fold-not-allowed ((pattern ref
))
1171 (defmethod fold-empty ((pattern one-or-more
))
1173 (if (typep (pattern-child pattern
) 'empty
)
1174 (pattern-child pattern
)
1177 (defmethod fold-empty ((pattern %parent
))
1178 (setf (pattern-child pattern
) (fold-empty (pattern-child pattern
)))
1183 (defmethod fold-empty ((pattern %combination
))
1184 (setf (pattern-a pattern
) (fold-empty (pattern-a pattern
)))
1185 (setf (pattern-b pattern
) (fold-empty (pattern-b pattern
)))
1188 (defmethod fold-empty ((pattern group
))
1191 ;; if any child is empty, choose the other
1192 ((typep (pattern-a pattern
) 'empty
) (pattern-b pattern
))
1193 ((typep (pattern-b pattern
) 'empty
) (pattern-a pattern
))
1196 (defmethod fold-empty ((pattern interleave
))
1199 ;; if any child is empty, choose the other
1200 ((typep (pattern-a pattern
) 'empty
) (pattern-b pattern
))
1201 ((typep (pattern-b pattern
) 'empty
) (pattern-a pattern
))
1204 (defmethod fold-empty ((pattern choice
))
1206 (if (typep (pattern-b pattern
) 'empty
)
1208 ((typep (pattern-a pattern
) 'empty
)
1209 (pattern-a pattern
))
1211 (rotatef (pattern-a pattern
) (pattern-b pattern
))
1217 (defmethod fold-empty ((pattern %leaf
))
1220 (defmethod fold-empty ((pattern data
))
1221 (when (pattern-except pattern
)
1222 (setf (pattern-except pattern
) (fold-empty (pattern-except pattern
))))
1227 (defmethod fold-empty ((pattern ref
))
1231 ;;;; name class overlap
1233 ;;; fixme: memorize this stuff?
1235 (defparameter !uri
(string (code-char 1)))
1236 (defparameter !lname
"")
1238 (defun classes-overlap-p (nc1 nc2
)
1239 (flet ((both-contain (x)
1240 (and (contains nc1
(car x
) (cdr x
))
1241 (contains nc2
(car x
) (cdr x
)))))
1242 (or (some #'both-contain
(representatives nc1
))
1243 (some #'both-contain
(representatives nc2
)))))
1245 (defmethod representatives ((nc any-name
))
1246 (cons (cons !uri
!lname
)
1247 (if (any-name-except nc
)
1248 (representatives (any-name-except nc
))
1251 (defmethod representatives ((nc ns-name
))
1252 (cons (cons (ns-name-uri nc
) !lname
)
1253 (if (ns-name-except nc
)
1254 (representatives (ns-name-except nc
))
1257 (defmethod representatives ((nc name
))
1258 (list (cons (name-uri nc
) (name-lname nc
))))
1260 (defmethod representatives ((nc name-class-choice
))
1261 (nconc (representatives (name-class-choice-a nc
))
1262 (representatives (name-class-choice-b nc
))))
1267 (defun finalize-definitions (pattern)
1268 (let ((defns (make-hash-table)))
1269 (labels ((recurse (p)
1272 (let ((target (pattern-target p
)))
1273 (unless (gethash target defns
)
1274 (setf (gethash target defns
) t
)
1275 (setf (defn-child target
) (recurse (defn-child target
))))
1276 (if (typep (defn-child target
) 'element
)
1278 (copy-pattern-tree (defn-child target
)))))
1282 (when (pattern-except p
)
1283 (setf (pattern-except p
) (recurse (pattern-except p
)))))
1285 (setf (pattern-child p
) (recurse (pattern-child p
))))
1287 (setf (pattern-a p
) (recurse (pattern-a p
)))
1288 (setf (pattern-b p
) (recurse (pattern-b p
))))
1294 for defn being each hash-key in defns
1297 (defun copy-pattern-tree (pattern)
1298 (labels ((recurse (p)
1299 (let ((q (copy-structure p
)))
1302 (when (pattern-except p
)
1303 (setf (pattern-except q
) (recurse (pattern-except p
)))))
1305 (setf (pattern-child q
) (recurse (pattern-child p
))))
1307 (setf (pattern-a q
) (recurse (pattern-a p
)))
1308 (setf (pattern-b q
) (recurse (pattern-b p
))))
1313 (defparameter *in-attribute-p
* nil
)
1314 (defparameter *in-one-or-more-p
* nil
)
1315 (defparameter *in-one-or-more
//group-or-interleave-p
* nil
)
1316 (defparameter *in-list-p
* nil
)
1317 (defparameter *in-data-except-p
* nil
)
1318 (defparameter *in-start-p
* nil
)
1320 (defun check-start-restrictions (pattern)
1321 (let ((*in-start-p
* t
))
1322 (check-restrictions pattern
)))
1324 (defun content-type-max (a b
)
1333 (defun groupable-max (a b
)
1334 (if (or (eq a
:empty
)
1336 (and (eq a
:complex
)
1338 (content-type-max a b
)
1341 (defmethod check-restrictions ((pattern attribute
))
1342 (when *in-attribute-p
*
1343 (rng-error nil
"nested attribute not allowed"))
1344 (when *in-one-or-more
//group-or-interleave-p
*
1345 (rng-error nil
"attribute not allowed in oneOrMore//group, oneOrMore//interleave"))
1347 (rng-error nil
"attribute in list not allowed"))
1348 (when *in-data-except-p
*
1349 (rng-error nil
"attribute in data/except not allowed"))
1351 (rng-error nil
"attribute in start not allowed"))
1352 (let ((*in-attribute-p
* t
))
1353 (values (if (check-restrictions (pattern-child pattern
))
1356 (list (pattern-name pattern
))
1359 (defmethod check-restrictions ((pattern ref
))
1360 (when *in-attribute-p
*
1361 (rng-error nil
"ref in attribute not allowed"))
1363 (rng-error nil
"ref in list not allowed"))
1364 (when *in-data-except-p
*
1365 (rng-error nil
"ref in data/except not allowed"))
1368 (list (pattern-name (defn-child (pattern-target pattern
))))
1371 (defmethod check-restrictions ((pattern one-or-more
))
1372 (when *in-data-except-p
*
1373 (rng-error nil
"oneOrMore in data/except not allowed"))
1375 (rng-error nil
"one-or-more in start not allowed"))
1376 (let* ((*in-one-or-more-p
* t
))
1377 (multiple-value-bind (x a e textp
)
1378 (check-restrictions (pattern-child pattern
))
1379 (values (groupable-max x x
) a e textp
))))
1381 (defmethod check-restrictions ((pattern group
))
1382 (when *in-data-except-p
*
1383 (rng-error nil
"group in data/except not allowed"))
1385 (rng-error nil
"group in start not allowed"))
1386 (let ((*in-one-or-more
//group-or-interleave-p
*
1387 *in-one-or-more-p
*))
1388 (multiple-value-bind (x a e tp
) (check-restrictions (pattern-a pattern
))
1389 (multiple-value-bind (y b f tq
) (check-restrictions (pattern-b pattern
))
1392 (when (classes-overlap-p nc1 nc2
)
1393 (rng-error nil
"attribute name overlap in group: ~A ~A"
1395 (values (groupable-max x y
)
1400 (defmethod check-restrictions ((pattern interleave
))
1402 (rng-error nil
"interleave in list not allowed"))
1403 (when *in-data-except-p
*
1404 (rng-error nil
"interleave in data/except not allowed"))
1406 (rng-error nil
"interleave in start not allowed"))
1407 (let ((*in-one-or-more
//group-or-interleave-p
*
1408 *in-one-or-more-p
*))
1409 (multiple-value-bind (x a e tp
) (check-restrictions (pattern-a pattern
))
1410 (multiple-value-bind (y b f tq
) (check-restrictions (pattern-b pattern
))
1413 (when (classes-overlap-p nc1 nc2
)
1414 (rng-error nil
"attribute name overlap in interleave: ~A ~A"
1418 (when (classes-overlap-p nc1 nc2
)
1419 (rng-error nil
"element name overlap in interleave: ~A ~A"
1422 (rng-error nil
"multiple text permitted by interleave"))
1423 (values (groupable-max x y
)
1428 (defmethod check-restrictions ((pattern choice
))
1429 (multiple-value-bind (x a e tp
) (check-restrictions (pattern-a pattern
))
1430 (multiple-value-bind (y b f tq
) (check-restrictions (pattern-b pattern
))
1431 (values (content-type-max x y
)
1436 (defmethod check-restrictions ((pattern list-pattern
))
1438 (rng-error nil
"nested list not allowed"))
1439 (when *in-data-except-p
*
1440 (rng-error nil
"list in data/except not allowed"))
1441 (let ((*in-list-p
* t
))
1442 (check-restrictions (pattern-child pattern
)))
1444 (rng-error nil
"list in start not allowed"))
1447 (defmethod check-restrictions ((pattern text
))
1449 (rng-error nil
"text in list not allowed"))
1450 (when *in-data-except-p
*
1451 (rng-error nil
"text in data/except not allowed"))
1453 (rng-error nil
"text in start not allowed"))
1454 (values :complex nil nil t
))
1456 (defmethod check-restrictions ((pattern data
))
1458 (rng-error nil
"data in start not allowed"))
1459 (when (pattern-except pattern
)
1460 (let ((*in-data-except-p
* t
))
1461 (check-restrictions (pattern-except pattern
))))
1464 (defmethod check-restrictions ((pattern value
))
1466 (rng-error nil
"value in start not allowed"))
1469 (defmethod check-restrictions ((pattern empty
))
1470 (when *in-data-except-p
*
1471 (rng-error nil
"empty in data/except not allowed"))
1473 (rng-error nil
"empty in start not allowed"))
1476 (defmethod check-restrictions ((pattern element
))
1477 (unless (check-restrictions (pattern-child pattern
))
1478 (rng-error nil
"restrictions on string sequences violated")))
1480 (defmethod check-restrictions ((pattern not-allowed
))