so geht das mit dem tokenizer
[cxml-rng.git] / parse.lisp
blobcf4879a446f2b57558f91664f64e77e8326f2f26
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
5 ;;; are met:
6 ;;;
7 ;;; * Redistributions of source code must retain the above copyright
8 ;;; notice, this list of conditions and the following disclaimer.
9 ;;;
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.
14 ;;;
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)
29 #+sbcl
30 (declaim (optimize (debug 2)))
33 ;;;; Errors
35 (define-condition rng-error (simple-error)
36 ((line-number :initarg :line-number :accessor rng-error-line-number)
37 (column-number :initarg :column-number :accessor rng-error-column-number)
38 (system-id :initarg :system-id :accessor rng-error-system-id))
39 (:documentation
40 "The class of all validation errors.
41 @see-slot{rng-error-line-number}
42 @see-slot{rng-error-column-number}
43 @see-slot{rng-error-system-id}"))
45 (setf (documentation 'rng-error-line-number 'function)
46 "@arg[instance]{an instance of @class{rng-error}}
47 @return{an integer, or nil}
48 Return the line number reported by the parser when the Relax NG error
49 was detected, or NIL if not available.")
51 (setf (documentation 'rng-error-column-number 'function)
52 "@arg[instance]{an instance of @class{rng-error}}
53 @return{an integer, or nil}
54 Return the column number reported by the parser when the Relax NG error
55 was detected, or NIL if not available.")
57 (setf (documentation 'rng-error-system-id 'function)
58 "@arg[instance]{an instance of @class{rng-error}}
59 @return{a puri:uri, or nil}
60 Return the System ID of the document being parsed when the Relax NG
61 error was detected, or NIL if not available.")
63 (defun rng-error (source fmt &rest args)
64 "@unexport{}"
65 (let ((s (make-string-output-stream)))
66 (apply #'format s fmt args)
67 (multiple-value-bind (line-number column-number system-id)
68 (etypecase source
69 (null)
70 (klacks:source
71 (values (klacks:current-line-number source)
72 (klacks:current-column-number source)
73 (klacks:current-system-id source)))
74 (sax:sax-parser-mixin
75 (values (sax:line-number source)
76 (sax:column-number source)
77 (sax:system-id source))))
78 (when (or line-number column-number system-id)
79 (format s "~& [ Error at line ~D, column ~D in ~S ]"
80 line-number
81 column-number
82 system-id))
83 (error 'rng-error
84 :format-control "~A"
85 :format-arguments (list (get-output-stream-string s))
86 :line-number line-number
87 :column-number column-number
88 :system-id system-id))))
91 ;;;; Parser
93 (defvar *datatype-library*)
94 (defvar *namespace-uri*)
95 (defvar *ns*)
96 (defvar *entity-resolver*)
97 (defvar *external-href-stack*)
98 (defvar *include-uri-stack*)
99 (defvar *include-body-p* nil)
100 (defvar *grammar*)
102 (defvar *debug* nil)
104 (defstruct (schema
105 (:constructor make-schema (start definitions)))
106 "An instance of this class represents a Relax NG grammar that has
107 been parsed and simplified.
108 @see-slot{schema-start}
109 @see-constructor{parse-schema}
110 @see{make-validator}
111 @see{serialize-schema} "
112 (start (missing) :type pattern)
113 (definitions (missing) :type list)
114 (interned-start nil :type (or null pattern))
115 (registratur nil :type (or null hash-table)))
117 (setf (documentation 'schema-start 'function)
118 "@arg[instance]{an instance of @class{schema}}
119 @return{the start pattern, an instance of @class{pattern}}
120 Reader function for the grammar's start pattern, from which all
121 of the grammar's patters are reachable.")
123 (defmethod print-object ((object schema) stream)
124 (print-unreadable-object (object stream :type t :identity t)))
126 (defun invoke-with-klacks-handler (fn source)
127 (if *debug*
128 (funcall fn)
129 (handler-case
130 (funcall fn)
131 (cxml:xml-parse-error (c)
132 (rng-error source "Cannot parse schema: ~A" c)))))
134 (defvar *validate-grammar* t)
135 (defparameter *relax-ng-grammar* nil)
137 (defun make-validating-source (input)
138 (let ((upstream (cxml:make-source input)))
139 (if *validate-grammar*
140 (klacks:make-tapping-source upstream
141 (make-validator *relax-ng-grammar*))
142 upstream)))
144 (defun parse-schema (input &key entity-resolver)
145 "@arg[input]{a string, pathname, stream, or xstream}
146 @arg[entity-resolver]{a function of two arguments, or NIL}
147 @return{a parsed @class{schema}}
148 @short{This function parses a Relax NG schema file in XML syntax}
149 and returns a parsed representation of that schema.
151 @code{input} can be any stream designator as understood by
152 @code{cxml:make-source}.
154 Note that namestrings are not valid arguments,
155 because they would be interpreted as XML source code. Use pathnames
156 instead.
158 @code{entity-resolver} can be passed as a function of two arguments.
159 It is invoked for every entity referenced by the
160 document with the entity's Public ID (a rod) and System ID (an
161 URI object) as arguments. The function may either return
162 nil, CXML will then try to resolve the entity as usual.
163 Alternatively it may return a Common Lisp stream specialized on
164 @code{(unsigned-byte 8)} which will be used instead.
166 @see{make-validator}"
167 (when *validate-grammar*
168 (unless *relax-ng-grammar*
169 (setf *relax-ng-grammar*
170 (let* ((*validate-grammar* nil)
171 (d (slot-value (asdf:find-system :cxml-rng)
172 'asdf::relative-pathname)))
173 (parse-schema (merge-pathnames "rng.rng" d))))))
174 (klacks:with-open-source (source (make-validating-source input))
175 (invoke-with-klacks-handler
176 (lambda ()
177 (klacks:find-event source :start-element)
178 (let* ((*datatype-library* "")
179 (*namespace-uri* "")
180 (*entity-resolver* entity-resolver)
181 (*external-href-stack* '())
182 (*include-uri-stack* '())
183 (*grammar* (make-grammar nil))
184 (start (p/pattern source)))
185 (unless start
186 (rng-error nil "empty grammar"))
187 (setf (grammar-start *grammar*)
188 (make-definition :name :start :child start))
189 (check-pattern-definitions source *grammar*)
190 (check-recursion start 0)
191 (multiple-value-bind (new-start defns)
192 (finalize-definitions start)
193 (setf start (fold-not-allowed new-start))
194 (dolist (defn defns)
195 (setf (defn-child defn) (fold-not-allowed (defn-child defn))))
196 (setf start (fold-empty start))
197 (dolist (defn defns)
198 (setf (defn-child defn) (fold-empty (defn-child defn)))))
199 (multiple-value-bind (new-start defns)
200 (finalize-definitions start)
201 (check-start-restrictions new-start)
202 (dolist (defn defns)
203 (check-restrictions (defn-child defn)))
204 (make-schema new-start defns))))
205 source)))
208 ;;;; pattern structures
210 (defstruct pattern
211 "@short{The superclass of all patterns.}
212 Instances of this class represent elements of the simplified syntax
213 for Relax NG.
215 Patterns are documented for introspective purposes and are not meant to
216 be modified by user code.
218 The start pattern of a schema is available through @fun{schema-start}.
220 @see{schema}"
221 (nullable :uninitialized))
223 (defmethod print-object :around ((object pattern) stream)
224 (if *debug*
225 (let ((*print-circle* t))
226 (call-next-method))
227 (print-unreadable-object (object stream :type t :identity t))))
229 (defstruct (%parent (:include pattern) (:conc-name "PATTERN-"))
230 child)
232 (defstruct (%named-pattern (:include %parent) (:conc-name "PATTERN-"))
233 name)
235 (setf (documentation 'pattern-name 'function)
236 "@arg[instance]{an instance of @class{pattern}}
237 @return{a @class{name-class}}
238 @short{Returns the @code{pattern}'s name class.}
240 This slot describes the name allowed for the current element or
241 attribute.
243 @see{element}
244 @see{attribute}")
246 (setf (documentation 'pattern-child 'function)
247 "@arg[instance]{an instance of @class{pattern}}
248 @return{an instance of @class{pattern}}
249 @short{Returns the pattern's sub-pattern.}
251 (Elements in the full Relax NG syntax allow more than one child
252 pattern, but simplification normalizes the representation so that
253 any such element has exactly one child.)
255 @see{element}
256 @see{attribute}
257 @see{one-or-more}
258 @see{list-pattern}
259 @see{choice}")
261 (defstruct (element (:include %named-pattern))
262 "@short{This pattern specifies that an element of a certain name class
263 is required.}
265 Its child pattern describes the attributes and child nodes
266 of this element.
267 @see-slot{pattern-name}
268 @see-slot{pattern-child}")
270 (defstruct (attribute (:include %named-pattern))
271 "@short{This pattern specifies that an attribute of a certain name class
272 is required.}
274 Its child pattern describes the type of the attribute's
275 contents.
276 @see-slot{pattern-name}
277 @see-slot{pattern-child}")
279 (defstruct (%combination (:include pattern) (:conc-name "PATTERN-"))
280 a b)
282 (setf (documentation 'pattern-a 'function)
283 "@arg[instance]{an instance of @class{pattern}}
284 @return{an instance of @class{pattern}}
285 @short{Returns the first of two sub-patterns the pattern instance has.}
287 (Elements in the full Relax NG syntax allow more than two child
288 patterns, but simplification normalizes the representation so that
289 any such element has exactly two children.)
291 @see{group}
292 @see{interleave}
293 @see{choice}")
295 (setf (documentation 'pattern-b 'function)
296 "@arg[instance]{an instance of @class{pattern}}
297 @return{an instance of @class{pattern}}
298 @short{Returns the second of two sub-patterns the pattern instance has.}
300 (Elements in the full Relax NG syntax allow more than two child
301 patterns, but simplification normalizes the representation so that
302 any such element has exactly two children.)
304 @see{group}
305 @see{interleave}
306 @see{choice}")
308 (defstruct (group
309 (:include %combination)
310 (:constructor make-group (a b)))
311 "@short{This pattern specifies that two subpatterns are
312 required at the current position in a specific order.}
314 @see-slot{pattern-a}
315 @see-slot{pattern-b}")
316 (defstruct (interleave
317 (:include %combination)
318 (:constructor make-interleave (a b)))
319 "@short{This pattern specifies that two possible subpatterns are
320 allowed to occur in any order at the current position.}
322 @see-slot{pattern-a}
323 @see-slot{pattern-b}")
324 (defstruct (choice
325 (:include %combination)
326 (:constructor make-choice (a b)))
327 "@short{This pattern specifies that one of two possible subpatterns are
328 allowed at the current position, given as its children.}
330 @see-slot{pattern-a}
331 @see-slot{pattern-b}")
332 (defstruct (after
333 (:include %combination)
334 (:constructor make-after (a b))))
336 (defstruct (one-or-more
337 (:include %parent)
338 (:constructor make-one-or-more (child)))
339 "@short{This pattern specifies that its subpattern is
340 allowed to occur at the current position one or more times.}
342 @see-slot{pattern-child}")
343 (defstruct (list-pattern
344 (:include %parent)
345 (:constructor make-list-pattern (child)))
346 "@short{This pattern specifies that a subpatterns is allowed multiple
347 times a the current position, with whitespace as a separator.}
349 @see-slot{pattern-child}")
351 (defstruct (ref
352 (:include pattern)
353 (:conc-name "PATTERN-")
354 (:constructor make-ref (target)))
355 "@short{This pattern references another part of the pattern graph.}
357 @code{ref} is the only pattern to introduce shared structure and
358 circularity into the pattern graph, by referring to elements defined
359 elsewhere.
361 (@code{ref} pattern in the full Relax NG syntax can be used to refer
362 to any pattern definition in the grammar. Simplification normalizes
363 the schema so that ref patterns only refer to definitions which have
364 an @code{element} as their child.)
366 @see-slot{pattern-element}"
367 crdepth
368 target)
370 (defun pattern-element (ref)
371 "@arg[ref]{an instance of @class{ref}}
372 @return{an instance of @class{element}}
373 @short{Returns the ref pattern's target.}
375 @code{ref} is the only pattern to introduce shared structure and
376 circularity into the pattern graph, by referring to elements defined
377 elsewhere.
379 (@code{ref} pattern in the full Relax NG syntax can be used to refer
380 to any pattern definition in the grammar. Simplification normalizes
381 the schema so that ref patterns only refer to definitions which have
382 an @code{element} as their child.)"
383 (defn-child (pattern-target ref)))
385 (defstruct (%leaf (:include pattern)))
387 (defstruct (empty (:include %leaf))
388 "@short{This pattern specifies that nothing more is expected at the current
389 position.}")
391 (defstruct (text (:include %leaf))
392 "@short{This pattern specifies that text is expected here.}")
394 (defstruct (%typed-pattern (:include %leaf) (:conc-name "PATTERN-"))
395 type)
397 (setf (documentation 'pattern-type 'function)
398 "@arg[instance]{an instance of @class{pattern}}
399 @return{a @class{cxml-types:data-type}}
400 @short{Returns the data type expected at this position.}
402 This type has already been parsed into an object. Its name and
403 the URI of its library can be queried from that object.
405 @see{data}
406 @see{value}
407 @see{cxml-types:type-name}
408 @see{cxml-types:type-library}")
410 (defstruct (value (:include %typed-pattern) (:conc-name "PATTERN-"))
411 "@short{This pattern specifies that a specific value is expected as text
412 here.}
414 The value expected is @code{pattern-value}, parsed from
415 @code{pattern-string} using @code{pattern-type}.
417 @see-slot{pattern-type}
418 @see-slot{pattern-value}
419 @see-slot{pattern-string}"
421 string
422 value)
424 (setf (documentation 'pattern-string 'function)
425 "@arg[instance]{an instance of @class{value}}
426 @return{a string}
427 @short{Returns the string expected at this position.}
429 This string is the lexical representation expected, not parsed into
430 a value object yet. The parsed object is available as
431 @fun{pattern-value}.
433 @see{pattern-type}")
435 (setf (documentation 'pattern-value 'function)
436 "@arg[instance]{an instance of @class{value}}
437 @return{an object as returned by @fun{cxml-types:parse}}
438 @short{Returns the value expected at this position.}
440 This object is the result of parsing @fun{pattern-string} using
441 @fun{pattern-type}.")
443 (defstruct (data (:include %typed-pattern) (:conc-name "PATTERN-"))
444 "@short{This pattern specifies that text of a specific data type is
445 expected.}
447 The data type instance stored in the @code{pattern-type} slot takes into
448 account additional paramaters, which can be retrieved using
449 @code{pattern-params} in their original form.
451 @see-slot{pattern-type}
452 @see-slot{pattern-params}
453 @see-slot{pattern-except}"
454 params
455 except)
457 (setf (documentation 'pattern-except 'function)
458 "@arg[instance]{an instance of @class{data}}
459 @return{a @class{pattern}, or @code{nil}}
460 @short{Returns the @code{data} instance's @code{except} pattern.}
462 In addition to a data type, @code{data} can specify that certain
463 values are @em{not} permitted. They are described using a pattern.
465 If this slot is @code{nil}, no exception is defined.")
467 (setf (documentation 'pattern-params 'function)
468 "@arg[instance]{an instance of @class{data}}
469 @return{a list of parameters}
470 @short{fixme}
472 fixme: params aren't actually exported yet.")
474 (defstruct (not-allowed (:include %leaf))
475 "@short{This pattern specifies that the part of the schema reached at
476 this point is not valid.}")
479 ;;;; non-pattern
481 (defstruct (grammar (:constructor make-grammar (parent)))
482 (start nil)
483 parent
484 (definitions (make-hash-table :test 'equal)))
486 (defstruct param
487 name
488 string)
490 ;; Clark calls this structure "RefPattern"
491 (defstruct (definition (:conc-name "DEFN-"))
492 name
493 combine-method
494 head-p
495 redefinition
496 child)
499 ;;; name-class
501 (defun missing ()
502 (error "missing arg"))
504 (defstruct name-class
505 "@short{The abstract superclass of all name-related classes.}
507 Name classes represent sets of permissible names for an element or
508 attribute.
510 Names are pairs of namespace URI and local-name.
512 @see{attribute}
513 @see{element}")
515 (defstruct (any-name (:include name-class)
516 (:constructor make-any-name (except)))
517 "@short{This name class allows any name.}
519 Exceptions are given as @code{any-name-except}.
521 @see-slot{any-name-except}"
522 (except (missing) :type (or null name-class)))
524 (setf (documentation 'any-name-except 'function)
525 "@arg[instance]{an instance of @class{any-name}}
526 @return{a @class{name-class} or @code{nil}}
528 Return the name class @em{not} allowed by this @code{any-name},
529 or @code{nil} if there is no such exception.")
531 (defstruct (name (:include name-class)
532 (:constructor make-name (uri lname)))
533 "@short{This name class allows only a specific name.}
535 A specific namespace URI and local name are expected.
537 @see-slot{name-uri}
538 @see-slot{name-lname}"
539 (uri (missing) :type string)
540 (lname (missing) :type string))
542 (setf (documentation 'name-uri 'function)
543 "@arg[instance]{an instance of @class{name}}
544 @return{a string}
545 Return the expected namespace URI.")
547 (setf (documentation 'name-lname 'function)
548 "@arg[instance]{an instance of @class{name}}
549 @return{a string}
550 Return the expected local name.")
552 (defstruct (ns-name (:include name-class)
553 (:constructor make-ns-name (uri except)))
554 "@short{This name class allows all names in a specific namespace}, with
555 possible exceptions.
557 A specific namespace URI is expected.
559 Exceptions are given as @code{ns-name-except}.
561 @see-slot{ns-name-uri}
562 @see-slot{ns-name-except}"
563 (uri (missing) :type string)
564 (except (missing) :type (or null name-class)))
566 (setf (documentation 'ns-name-uri 'function)
567 "@arg[instance]{an instance of @class{ns-name}}
568 @return{a string}
569 Return the expected namespace URI.")
571 (setf (documentation 'ns-name-except 'function)
572 "@arg[instance]{an instance of @class{ns-name}}
573 @return{a @class{name-class} or @code{nil}}
575 Return the name class @em{not} allowed by this @code{ns-name},
576 or @code{nil} if there is no such exception.")
578 (defstruct (name-class-choice (:include name-class)
579 (:constructor make-name-class-choice (a b)))
580 "@short{This name class represents the union of two other name classes.}
582 @see-slot{name-class-choice-a}
583 @see-slot{name-class-choice-b}"
584 (a (missing) :type name-class)
585 (b (missing) :type name-class))
587 (setf (documentation 'name-class-choice-a 'function)
588 "@arg[instance]{an instance of @class{name-class-choice}}
589 @return{a @class{name-class}}
590 Returns the 'first' of two name classes that are allowed.")
592 (setf (documentation 'name-class-choice-b 'function)
593 "@arg[instance]{an instance of @class{name-class-choice}}
594 @return{a @class{name-class}}
595 Returns the 'second' of two name classes that are allowed.")
597 (defun simplify-nc-choice (values)
598 (zip #'make-name-class-choice values))
601 ;;;; parser
603 (defvar *rng-namespace* "http://relaxng.org/ns/structure/1.0")
605 (defun skip-foreign* (source)
606 (loop
607 (case (klacks:peek-next source)
608 (:start-element (skip-foreign source))
609 (:end-element (return)))))
611 (defun skip-to-native (source)
612 (loop
613 (case (klacks:peek source)
614 (:start-element
615 (when (equal (klacks:current-uri source) *rng-namespace*)
616 (return))
617 (klacks:serialize-element source nil))
618 (:end-element (return)))
619 (klacks:consume source)))
621 (defun consume-and-skip-to-native (source)
622 (klacks:consume source)
623 (skip-to-native source))
625 (defun skip-foreign (source)
626 (when (equal (klacks:current-uri source) *rng-namespace*)
627 (rng-error source
628 "invalid schema: ~A not allowed here"
629 (klacks:current-lname source)))
630 (klacks:serialize-element source nil))
632 (defun attribute (lname attrs)
633 "@unexport{}"
634 (let ((a (sax:find-attribute-ns "" lname attrs)))
635 (if a
636 (sax:attribute-value a)
637 nil)))
639 (defparameter *whitespace*
640 (format nil "~C~C~C~C"
641 (code-char 9)
642 (code-char 32)
643 (code-char 13)
644 (code-char 10)))
646 (defun ntc (lname source-or-attrs)
647 ;; used for (n)ame, (t)ype, and (c)ombine, this also strings whitespace
648 (let* ((attrs
649 (if (listp source-or-attrs)
650 source-or-attrs
651 (klacks:list-attributes source-or-attrs)))
652 (a (sax:find-attribute-ns "" lname attrs)))
653 (if a
654 (string-trim *whitespace* (sax:attribute-value a))
655 nil)))
657 (defmacro with-library-and-ns (attrs &body body)
658 `(invoke-with-library-and-ns (lambda () ,@body) ,attrs))
660 (defun invoke-with-library-and-ns (fn attrs)
661 (let* ((dl (attribute "datatypeLibrary" attrs))
662 (ns (attribute "ns" attrs))
663 (*datatype-library* (if dl (escape-uri dl) *datatype-library*))
664 (*namespace-uri* (or ns *namespace-uri*))
665 (*ns* ns))
666 ;; FIXME: Ganz boese gehackt -- gerade so, dass wir die Relax NG
667 ;; Test-Suite bestehen.
668 (when (and dl
669 (not (zerop (length *datatype-library*)))
670 ;; scheme pruefen, und es muss was folgen
671 (or (not (cl-ppcre:all-matches
672 "^[a-zA-Z][a-zA-Z0-9+.-]*:.+"
673 *datatype-library*))
674 ;; keine kaputten %te, keine #
675 (cl-ppcre:all-matches
676 "(%$|%.$|%[^0-9A-Fa-f][^0-9A-Fa-f]|#)"
677 *datatype-library*)))
678 (rng-error nil "malformed datatypeLibrary: ~A" *datatype-library*))
679 (funcall fn)))
681 (defun p/pattern (source)
682 (let* ((lname (klacks:current-lname source))
683 (attrs (klacks:list-attributes source)))
684 (with-library-and-ns attrs
685 (case (find-symbol lname :keyword)
686 (:|element| (p/element source (ntc "name" attrs)))
687 (:|attribute| (p/attribute source (ntc "name" attrs)))
688 (:|group| (p/combination #'groupify source))
689 (:|interleave| (p/combination #'interleave-ify source))
690 (:|choice| (p/combination #'choice-ify source))
691 (:|optional| (p/optional source))
692 (:|zeroOrMore| (p/zero-or-more source))
693 (:|oneOrMore| (p/one-or-more source))
694 (:|list| (p/list source))
695 (:|mixed| (p/mixed source))
696 (:|ref| (p/ref source))
697 (:|parentRef| (p/parent-ref source))
698 (:|empty| (p/empty source))
699 (:|text| (p/text source))
700 (:|value| (p/value source))
701 (:|data| (p/data source))
702 (:|notAllowed| (p/not-allowed source))
703 (:|externalRef| (p/external-ref source))
704 (:|grammar| (p/grammar source))
705 (t (skip-foreign source))))))
707 (defun p/pattern+ (source)
708 (let ((children nil))
709 (loop
710 (case (klacks:peek source)
711 (:start-element
712 (let ((p (p/pattern source))) (when p (push p children))))
713 (:end-element
714 (return))
716 (klacks:consume source))))
717 (unless children
718 (rng-error source "empty element"))
719 (nreverse children)))
721 (defun p/pattern? (source)
722 (let ((result nil))
723 (loop
724 (skip-to-native source)
725 (case (klacks:peek source)
726 (:start-element
727 (when result
728 (rng-error source "at most one pattern expected here"))
729 (setf result (p/pattern source)))
730 (:end-element
731 (return))
733 (klacks:consume source))))
734 result))
736 (defun p/element (source name)
737 (klacks:expecting-element (source "element")
738 (let ((elt (make-element)))
739 (consume-and-skip-to-native source)
740 (if name
741 (setf (pattern-name elt) (destructure-name source name))
742 (setf (pattern-name elt) (p/name-class source)))
743 (skip-to-native source)
744 (setf (pattern-child elt) (groupify (p/pattern+ source)))
745 (make-ref (make-definition :name (gensym "ANONYMOUS") :child elt)))))
747 (defvar *attribute-namespace-p* nil)
749 (defun p/attribute (source name)
750 (klacks:expecting-element (source "attribute")
751 (let ((result (make-attribute)))
752 (consume-and-skip-to-native source)
753 (if name
754 (setf (pattern-name result)
755 (let ((*namespace-uri* (or *ns* ""))
756 (*attribute-namespace-p* t))
757 (destructure-name source name)))
758 (setf (pattern-name result)
759 (let ((*attribute-namespace-p* t))
760 (p/name-class source))))
761 (skip-to-native source)
762 (setf (pattern-child result)
763 (or (p/pattern? source) (make-text)))
764 result)))
766 (defun p/combination (zipper source)
767 (klacks:expecting-element (source)
768 (consume-and-skip-to-native source)
769 (funcall zipper (p/pattern+ source))))
771 (defun p/one-or-more (source)
772 (klacks:expecting-element (source "oneOrMore")
773 (consume-and-skip-to-native source)
774 (let ((children (p/pattern+ source)))
775 (make-one-or-more (groupify children)))))
777 (defun p/zero-or-more (source)
778 (klacks:expecting-element (source "zeroOrMore")
779 (consume-and-skip-to-native source)
780 (let ((children (p/pattern+ source)))
781 (make-choice (make-one-or-more (groupify children))
782 (make-empty)))))
784 (defun p/optional (source)
785 (klacks:expecting-element (source "optional")
786 (consume-and-skip-to-native source)
787 (let ((children (p/pattern+ source)))
788 (make-choice (groupify children) (make-empty)))))
790 (defun p/list (source)
791 (klacks:expecting-element (source "list")
792 (consume-and-skip-to-native source)
793 (let ((children (p/pattern+ source)))
794 (make-list-pattern (groupify children)))))
796 (defun p/mixed (source)
797 (klacks:expecting-element (source "mixed")
798 (consume-and-skip-to-native source)
799 (let ((children (p/pattern+ source)))
800 (make-interleave (groupify children) (make-text)))))
802 (defun p/ref (source)
803 (klacks:expecting-element (source "ref")
804 (prog1
805 (let* ((name (ntc "name" source))
806 (pdefinition
807 (or (find-definition name)
808 (setf (find-definition name)
809 (make-definition :name name :child nil)))))
810 (make-ref pdefinition))
811 (skip-foreign* source))))
813 (defun p/parent-ref (source)
814 (klacks:expecting-element (source "parentRef")
815 (prog1
816 (let* ((name (ntc "name" source))
817 (grammar (grammar-parent *grammar*))
818 (pdefinition
819 (or (find-definition name grammar)
820 (setf (find-definition name grammar)
821 (make-definition :name name :child nil)))))
822 (make-ref pdefinition))
823 (skip-foreign* source))))
825 (defun p/empty (source)
826 (klacks:expecting-element (source "empty")
827 (skip-foreign* source)
828 (make-empty)))
830 (defun p/text (source)
831 (klacks:expecting-element (source "text")
832 (skip-foreign* source)
833 (make-text)))
835 (defun consume-and-parse-characters (source)
836 ;; fixme
837 (let ((tmp ""))
838 (loop
839 (multiple-value-bind (key data) (klacks:peek-next source)
840 (case key
841 (:characters
842 (setf tmp (concatenate 'string tmp data)))
843 (:end-element (return)))))
844 tmp))
846 (defun p/value (source)
847 (klacks:expecting-element (source "value")
848 (let* ((type (ntc "type" source))
849 (string (consume-and-parse-characters source))
850 (ns *namespace-uri*)
851 (dl *datatype-library*))
852 (unless type
853 (setf type "token")
854 (setf dl ""))
855 (let ((data-type
856 (cxml-types:find-type (and dl (find-symbol dl :keyword)) type))
857 (vc (cxml-types:make-klacks-validation-context source)))
858 (unless data-type
859 (rng-error source "type not found: ~A/~A" type dl))
860 (make-value :string string
861 :value (cxml-types:parse data-type string vc)
862 :type data-type
863 :ns ns)))))
865 (defun p/data (source)
866 (klacks:expecting-element (source "data")
867 (let* ((type (ntc "type" source))
868 (params '())
869 (except nil))
870 (loop
871 (multiple-value-bind (key uri lname)
872 (klacks:peek-next source)
874 (case key
875 (:start-element
876 (case (find-symbol lname :keyword)
877 (:|param| (push (p/param source) params))
878 (:|except|
879 (setf except (p/except-pattern source))
880 (skip-to-native source)
881 (return))
882 (t (skip-foreign source))))
883 (:end-element
884 (return)))))
885 (setf params (nreverse params))
886 (let* ((dl *datatype-library*)
887 (data-type (apply #'cxml-types:find-type
888 (and dl (find-symbol dl :keyword))
889 type
890 (loop
891 for p in params
892 collect (find-symbol (param-name p)
893 :keyword)
894 collect (param-string p)))))
895 (unless data-type
896 (rng-error source "type not found: ~A/~A" type dl))
897 (make-data
898 :type data-type
899 :params params
900 :except except)))))
902 (defun p/param (source)
903 (klacks:expecting-element (source "param")
904 (let ((name (ntc "name" source))
905 (string (consume-and-parse-characters source)))
906 (make-param :name name :string string))))
908 (defun p/except-pattern (source)
909 (klacks:expecting-element (source "except")
910 (with-library-and-ns (klacks:list-attributes source)
911 (klacks:consume source)
912 (choice-ify (p/pattern+ source)))))
914 (defun p/not-allowed (source)
915 (klacks:expecting-element (source "notAllowed")
916 (consume-and-skip-to-native source)
917 (make-not-allowed)))
919 (defun safe-parse-uri (source str &optional base)
920 (when (zerop (length str))
921 (rng-error source "missing URI"))
922 (let ((uri
923 (handler-case
924 (if base
925 (puri:merge-uris str base)
926 (puri:parse-uri str))
927 (puri:uri-parse-error ()
928 (rng-error source "invalid URI: ~A" str)))))
929 (when (and (eq (puri:uri-scheme uri) :file)
930 (puri:uri-fragment uri))
931 (rng-error source "Forbidden fragment in URI: ~A" str))
932 uri))
934 (defun p/external-ref (source)
935 (klacks:expecting-element (source "externalRef")
936 (let* ((href
937 (escape-uri (attribute "href" (klacks:list-attributes source))))
938 (base (klacks:current-xml-base source))
939 (uri (safe-parse-uri source href base)))
940 (when (find uri *include-uri-stack* :test #'puri:uri=)
941 (rng-error source "looping include"))
942 (prog1
943 (let* ((*include-uri-stack* (cons uri *include-uri-stack*))
944 (xstream
945 (cxml::xstream-open-extid* *entity-resolver* nil uri)))
946 (klacks:with-open-source (source (make-validating-source xstream))
947 (invoke-with-klacks-handler
948 (lambda ()
949 (klacks:find-event source :start-element)
950 (let ((*datatype-library* ""))
951 (p/pattern source)))
952 source)))
953 (skip-foreign* source)))))
955 (defun p/grammar (source &optional grammar)
956 (klacks:expecting-element (source "grammar")
957 (consume-and-skip-to-native source)
958 (let ((*grammar* (or grammar (make-grammar *grammar*)))
959 (includep grammar))
960 (process-grammar-content* source)
961 (unless (or includep (grammar-start *grammar*))
962 (rng-error source "no <start> in grammar"))
963 (unless includep
964 (check-pattern-definitions source *grammar*)
965 (defn-child (grammar-start *grammar*))))))
967 (defvar *include-start*)
968 (defvar *include-definitions*)
970 (defun process-grammar-content* (source &key disallow-include)
971 (loop
972 (multiple-value-bind (key uri lname) (klacks:peek source)
974 (case key
975 (:start-element
976 (with-library-and-ns (klacks:list-attributes source)
977 (case (find-symbol lname :keyword)
978 (:|start| (process-start source))
979 (:|define| (process-define source))
980 (:|div| (process-div source))
981 (:|include|
982 (when disallow-include
983 (rng-error source "nested include not permitted"))
984 (process-include source))
986 (skip-foreign source)))))
987 (:end-element
988 (return))))
989 (klacks:consume source)))
991 (defun process-start (source)
992 (klacks:expecting-element (source "start")
993 (let* ((combine0 (ntc "combine" source))
994 (combine
995 (when combine0
996 (find-symbol (string-upcase combine0) :keyword)))
997 (child
998 (progn
999 (consume-and-skip-to-native source)
1000 (p/pattern source)))
1001 (pdefinition (grammar-start *grammar*)))
1002 (skip-foreign* source)
1003 ;; fixme: shared code with process-define
1004 (unless pdefinition
1005 (setf pdefinition (make-definition :name :start :child nil))
1006 (setf (grammar-start *grammar*) pdefinition))
1007 (when *include-body-p*
1008 (setf *include-start* pdefinition))
1009 (cond
1010 ((defn-child pdefinition)
1011 (ecase (defn-redefinition pdefinition)
1012 (:not-being-redefined
1013 (when (and combine
1014 (defn-combine-method pdefinition)
1015 (not (eq combine
1016 (defn-combine-method pdefinition))))
1017 (rng-error source "conflicting combine values for <start>"))
1018 (unless combine
1019 (when (defn-head-p pdefinition)
1020 (rng-error source "multiple definitions for <start>"))
1021 (setf (defn-head-p pdefinition) t))
1022 (unless (defn-combine-method pdefinition)
1023 (setf (defn-combine-method pdefinition) combine))
1024 (setf (defn-child pdefinition)
1025 (case (defn-combine-method pdefinition)
1026 (:choice
1027 (make-choice (defn-child pdefinition) child))
1028 (:interleave
1029 (make-interleave (defn-child pdefinition) child)))))
1030 (:being-redefined-and-no-original
1031 (setf (defn-redefinition pdefinition)
1032 :being-redefined-and-original))
1033 (:being-redefined-and-original)))
1035 (setf (defn-child pdefinition) child)
1036 (setf (defn-combine-method pdefinition) combine)
1037 (setf (defn-head-p pdefinition) (null combine))
1038 (setf (defn-redefinition pdefinition) :not-being-redefined))))))
1040 (defun zip (constructor children)
1041 (cond
1042 ((null children)
1043 (rng-error nil "empty choice?"))
1044 ((null (cdr children))
1045 (car children))
1047 (destructuring-bind (a b &rest rest)
1048 children
1049 (zip constructor (cons (funcall constructor a b) rest))))))
1051 (defun choice-ify (children) (zip #'make-choice children))
1052 (defun groupify (children) (zip #'make-group children))
1053 (defun interleave-ify (children) (zip #'make-interleave children))
1055 (defun find-definition (name &optional (grammar *grammar*))
1056 (gethash name (grammar-definitions grammar)))
1058 (defun (setf find-definition) (newval name &optional (grammar *grammar*))
1059 (setf (gethash name (grammar-definitions grammar)) newval))
1061 (defun process-define (source)
1062 (klacks:expecting-element (source "define")
1063 (let* ((name (ntc "name" source))
1064 (combine0 (ntc "combine" source))
1065 (combine (when combine0
1066 (find-symbol (string-upcase combine0) :keyword)))
1067 (child (groupify
1068 (progn
1069 (consume-and-skip-to-native source)
1070 (p/pattern+ source))))
1071 (pdefinition (find-definition name)))
1072 (unless pdefinition
1073 (setf pdefinition (make-definition :name name :child nil))
1074 (setf (find-definition name) pdefinition))
1075 (when *include-body-p*
1076 (push pdefinition *include-definitions*))
1077 (cond
1078 ((defn-child pdefinition)
1079 (case (defn-redefinition pdefinition)
1080 (:not-being-redefined
1081 (when (and combine
1082 (defn-combine-method pdefinition)
1083 (not (eq combine
1084 (defn-combine-method pdefinition))))
1085 (rng-error source "conflicting combine values for ~A" name))
1086 (unless combine
1087 (when (defn-head-p pdefinition)
1088 (rng-error source "multiple definitions for ~A" name))
1089 (setf (defn-head-p pdefinition) t))
1090 (unless (defn-combine-method pdefinition)
1091 (setf (defn-combine-method pdefinition) combine))
1092 (setf (defn-child pdefinition)
1093 (case (defn-combine-method pdefinition)
1094 (:choice
1095 (make-choice (defn-child pdefinition) child))
1096 (:interleave
1097 (make-interleave (defn-child pdefinition) child)))))
1098 (:being-redefined-and-no-original
1099 (setf (defn-redefinition pdefinition)
1100 :being-redefined-and-original))
1101 (:being-redefined-and-original)))
1103 (setf (defn-child pdefinition) child)
1104 (setf (defn-combine-method pdefinition) combine)
1105 (setf (defn-head-p pdefinition) (null combine))
1106 (setf (defn-redefinition pdefinition) :not-being-redefined))))))
1108 (defun process-div (source)
1109 (klacks:expecting-element (source "div")
1110 (consume-and-skip-to-native source)
1111 (process-grammar-content* source)))
1113 (defun reset-definition-for-include (defn)
1114 (setf (defn-combine-method defn) nil)
1115 (setf (defn-redefinition defn) :being-redefined-and-no-original)
1116 (setf (defn-head-p defn) nil))
1118 (defun restore-definition (defn original)
1119 (setf (defn-combine-method defn) (defn-combine-method original))
1120 (setf (defn-redefinition defn) (defn-redefinition original))
1121 (setf (defn-head-p defn) (defn-head-p original)))
1123 (defun process-include (source)
1124 (klacks:expecting-element (source "include")
1125 (let* ((href
1126 (escape-uri (attribute "href" (klacks:list-attributes source))))
1127 (base (klacks:current-xml-base source))
1128 (uri (safe-parse-uri source href base))
1129 (*include-start* nil)
1130 (*include-definitions* '()))
1131 (consume-and-skip-to-native source)
1132 (let ((*include-body-p* t))
1133 (process-grammar-content* source :disallow-include t))
1134 (let ((tmp-start
1135 (when *include-start*
1136 (prog1
1137 (copy-structure *include-start*)
1138 (reset-definition-for-include *include-start*))))
1139 (tmp-defns
1140 (loop
1141 for defn in *include-definitions*
1142 collect
1143 (prog1
1144 (copy-structure defn)
1145 (reset-definition-for-include defn)))))
1146 (when (find uri *include-uri-stack* :test #'puri:uri=)
1147 (rng-error source "looping include"))
1148 (let* ((*include-uri-stack* (cons uri *include-uri-stack*))
1149 (xstream (cxml::xstream-open-extid* *entity-resolver* nil uri)))
1150 (klacks:with-open-source (source (make-validating-source xstream))
1151 (invoke-with-klacks-handler
1152 (lambda ()
1153 (klacks:find-event source :start-element)
1154 (let ((*datatype-library* ""))
1155 (p/grammar source *grammar*)))
1156 source))
1157 (when tmp-start
1158 (when (eq (defn-redefinition *include-start*)
1159 :being-redefined-and-no-original)
1160 (rng-error source "start not found in redefinition of grammar"))
1161 (restore-definition *include-start* tmp-start))
1162 (dolist (copy tmp-defns)
1163 (let ((defn (gethash (defn-name copy)
1164 (grammar-definitions *grammar*))))
1165 (when (eq (defn-redefinition defn)
1166 :being-redefined-and-no-original)
1167 (rng-error source "redefinition not found in grammar"))
1168 (restore-definition defn copy)))
1169 nil)))))
1171 (defun check-pattern-definitions (source grammar)
1172 (when (and (grammar-start grammar)
1173 (eq (defn-redefinition (grammar-start grammar))
1174 :being-redefined-and-no-original))
1175 (rng-error source "start not found in redefinition of grammar"))
1176 (loop for defn being each hash-value in (grammar-definitions grammar) do
1177 (when (eq (defn-redefinition defn) :being-redefined-and-no-original)
1178 (rng-error source "redefinition not found in grammar"))
1179 (unless (defn-child defn)
1180 (rng-error source "unresolved reference to ~A" (defn-name defn)))))
1182 (defvar *any-name-allowed-p* t)
1183 (defvar *ns-name-allowed-p* t)
1185 (defun destructure-name (source qname)
1186 (multiple-value-bind (uri lname)
1187 (klacks:decode-qname qname source)
1188 (setf uri (or uri *namespace-uri*))
1189 (when (and *attribute-namespace-p*
1190 (or (and (equal lname "xmlns") (equal uri ""))
1191 (equal uri "http://www.w3.org/2000/xmlns")))
1192 (rng-error source "namespace attribute not permitted"))
1193 (make-name uri lname)))
1195 (defun p/name-class (source)
1196 (klacks:expecting-element (source)
1197 (with-library-and-ns (klacks:list-attributes source)
1198 (case (find-symbol (klacks:current-lname source) :keyword)
1199 (:|name|
1200 (let ((qname (string-trim *whitespace*
1201 (consume-and-parse-characters source))))
1202 (destructure-name source qname)))
1203 (:|anyName|
1204 (unless *any-name-allowed-p*
1205 (rng-error source "anyname now permitted in except"))
1206 (klacks:consume source)
1207 (prog1
1208 (let ((*any-name-allowed-p* nil))
1209 (make-any-name (p/except-name-class? source)))
1210 (skip-to-native source)))
1211 (:|nsName|
1212 (unless *ns-name-allowed-p*
1213 (rng-error source "nsname now permitted in except"))
1214 (let ((uri *namespace-uri*)
1215 (*any-name-allowed-p* nil)
1216 (*ns-name-allowed-p* nil))
1217 (when (and *attribute-namespace-p*
1218 (equal uri "http://www.w3.org/2000/xmlns"))
1219 (rng-error source "namespace attribute not permitted"))
1220 (klacks:consume source)
1221 (prog1
1222 (make-ns-name uri (p/except-name-class? source))
1223 (skip-to-native source))))
1224 (:|choice|
1225 (klacks:consume source)
1226 (simplify-nc-choice (p/name-class* source)))
1228 (rng-error source "invalid child in except"))))))
1230 (defun p/name-class* (source)
1231 (let ((results nil))
1232 (loop
1233 (skip-to-native source)
1234 (case (klacks:peek source)
1235 (:start-element (push (p/name-class source) results))
1236 (:end-element (return)))
1237 (klacks:consume source))
1238 (nreverse results)))
1240 (defun p/except-name-class? (source)
1241 (skip-to-native source)
1242 (multiple-value-bind (key uri lname)
1243 (klacks:peek source)
1245 (if (and (eq key :start-element)
1246 (string= (find-symbol lname :keyword) "except"))
1247 (p/except-name-class source)
1248 nil)))
1250 (defun p/except-name-class (source)
1251 (klacks:expecting-element (source "except")
1252 (with-library-and-ns (klacks:list-attributes source)
1253 (klacks:consume source)
1254 (let ((x (p/name-class* source)))
1255 (if (cdr x)
1256 (simplify-nc-choice x)
1257 (car x))))))
1259 (defun escape-uri (string)
1260 (with-output-to-string (out)
1261 (loop for c across (cxml::rod-to-utf8-string string) do
1262 (let ((code (char-code c)))
1263 ;; http://www.w3.org/TR/xlink/#link-locators
1264 (if (or (>= code 127) (<= code 32) (find c "<>\"{}|\\^`"))
1265 (format out "%~2,'0X" code)
1266 (write-char c out))))))
1269 ;;;; unparsing
1271 (defvar *definitions-to-names*)
1272 (defvar *seen-names*)
1274 (defun serialization-name (defn)
1275 (or (gethash defn *definitions-to-names*)
1276 (setf (gethash defn *definitions-to-names*)
1277 (let ((name (if (gethash (defn-name defn) *seen-names*)
1278 (format nil "~A-~D"
1279 (defn-name defn)
1280 (hash-table-count *seen-names*))
1281 (defn-name defn))))
1282 (setf (gethash name *seen-names*) defn)
1283 name))))
1285 (defun serialize-schema (schema sink)
1286 "@arg[schema]{a Relax NG @class{schema}}
1287 @arg[sink]{a SAX handler}
1288 @return{the result of @code{sax:end-document}}
1289 @short{This function serializes a parsed Relax NG back into XML syntax.}
1291 Note that the schema represented in memory has gone through simplification
1292 as is textually different from the original XML document.
1294 @see{parse-schema}"
1295 (cxml:with-xml-output sink
1296 (let ((*definitions-to-names* (make-hash-table))
1297 (*seen-names* (make-hash-table :test 'equal)))
1298 (cxml:with-element "grammar"
1299 (cxml:with-element "start"
1300 (serialize-pattern (schema-start schema)))
1301 (loop for defn being each hash-key in *definitions-to-names* do
1302 (serialize-definition defn))))))
1304 (defun serialize-pattern (pattern)
1305 (etypecase pattern
1306 (element
1307 (cxml:with-element "element"
1308 (serialize-name (pattern-name pattern))
1309 (serialize-pattern (pattern-child pattern))))
1310 (attribute
1311 (cxml:with-element "attribute"
1312 (serialize-name (pattern-name pattern))
1313 (serialize-pattern (pattern-child pattern))))
1314 (%combination
1315 (cxml:with-element
1316 (etypecase pattern
1317 (group "group")
1318 (interleave "interleave")
1319 (choice "choice"))
1320 (serialize-pattern (pattern-a pattern))
1321 (serialize-pattern (pattern-b pattern))))
1322 (one-or-more
1323 (cxml:with-element "oneOrMore"
1324 (serialize-pattern (pattern-child pattern))))
1325 (list-pattern
1326 (cxml:with-element "list"
1327 (serialize-pattern (pattern-child pattern))))
1328 (ref
1329 (cxml:with-element "ref"
1330 (cxml:attribute "name" (serialization-name (pattern-target pattern)))))
1331 (empty
1332 (cxml:with-element "empty"))
1333 (not-allowed
1334 (cxml:with-element "notAllowed"))
1335 (text
1336 (cxml:with-element "text"))
1337 (value
1338 (cxml:with-element "value"
1339 (let ((type (pattern-type pattern)))
1340 (cxml:attribute "datatype-library"
1341 (symbol-name (cxml-types:type-library type)))
1342 (cxml:attribute "type" (cxml-types:type-name type)))
1343 (cxml:attribute "ns" (pattern-ns pattern))
1344 (cxml:text (pattern-string pattern))))
1345 (data
1346 (cxml:with-element "value"
1347 (let ((type (pattern-type pattern)))
1348 (cxml:attribute "datatype-library"
1349 (symbol-name (cxml-types:type-library type)))
1350 (cxml:attribute "type" (cxml-types:type-name type)))
1351 (dolist (param (pattern-params pattern))
1352 (cxml:with-element "param"
1353 (cxml:attribute "name" (param-name param))
1354 (cxml:text (param-string param))))
1355 (when (pattern-except pattern)
1356 (cxml:with-element "except"
1357 (serialize-pattern (pattern-except pattern))))))))
1359 (defun serialize-definition (defn)
1360 (cxml:with-element "define"
1361 (cxml:attribute "name" (serialization-name defn))
1362 (serialize-pattern (defn-child defn))))
1364 (defun serialize-name (name)
1365 (etypecase name
1366 (name
1367 (cxml:with-element "name"
1368 (cxml:attribute "ns" (name-uri name))
1369 (cxml:text (name-lname name))))
1370 (any-name
1371 (cxml:with-element "anyName"
1372 (when (any-name-except name)
1373 (serialize-except-name (any-name-except name)))))
1374 (ns-name
1375 (cxml:with-element "anyName"
1376 (cxml:attribute "ns" (ns-name-uri name))
1377 (when (ns-name-except name)
1378 (serialize-except-name (ns-name-except name)))))
1379 (name-class-choice
1380 (cxml:with-element "choice"
1381 (serialize-name (name-class-choice-a name))
1382 (serialize-name (name-class-choice-b name))))))
1384 (defun serialize-except-name (spec)
1385 (cxml:with-element "except"
1386 (serialize-name spec)))
1389 ;;;; simplification
1391 ;;; 4.1 Annotations
1392 ;;; Foreign attributes and elements are removed implicitly while parsing.
1394 ;;; 4.2 Whitespace
1395 ;;; All character data is discarded while parsing (which can only be
1396 ;;; whitespace after validation).
1398 ;;; Whitespace in name, type, and combine attributes is stripped while
1399 ;;; parsing. Ditto for <name/>.
1401 ;;; 4.3. datatypeLibrary attribute
1402 ;;; Escaping is done by p/pattern.
1403 ;;; Attribute value defaulting is done using *datatype-library*; only
1404 ;;; p/data and p/value record the computed value.
1406 ;;; 4.4. type attribute of value element
1407 ;;; Done by p/value.
1409 ;;; 4.5. href attribute
1410 ;;; Escaping is done by process-include and p/external-ref.
1412 ;;; FIXME: Mime-type handling should be the job of the entity resolver,
1413 ;;; but that requires xstream hacking.
1415 ;;; 4.6. externalRef element
1416 ;;; Done by p/external-ref.
1418 ;;; 4.7. include element
1419 ;;; Done by process-include.
1421 ;;; 4.8. name attribute of element and attribute elements
1422 ;;; `name' is stored as a slot, not a child. Done by p/element and
1423 ;;; p/attribute.
1425 ;;; 4.9. ns attribute
1426 ;;; done by p/name-class, p/value, p/element, p/attribute
1428 ;;; 4.10. QNames
1429 ;;; done by p/name-class
1431 ;;; 4.11. div element
1432 ;;; Legen wir gar nicht erst an.
1434 ;;; 4.12. 4.13 4.14 4.15
1435 ;;; beim anlegen
1437 ;;; 4.16
1438 ;;; p/name-class
1439 ;;; -- ausser der sache mit den datentypen
1441 ;;; 4.17, 4.18, 4.19
1442 ;;; Ueber die Grammar-und Definition Objekte, wie von James Clark
1443 ;;; beschrieben.
1445 ;;; Dabei werden keine Umbenennungen vorgenommen, weil Referenzierung
1446 ;;; durch Aufbei der Graphenstruktur zwischen ref und Definition
1447 ;;; erfolgt und Namen dann bereits aufgeloest sind. Wir benennen
1448 ;;; dafuer beim Serialisieren um.
1450 (defmethod check-recursion ((pattern element) depth)
1451 (check-recursion (pattern-child pattern) (1+ depth)))
1453 (defmethod check-recursion ((pattern ref) depth)
1454 (when (eql (pattern-crdepth pattern) depth)
1455 (rng-error nil "infinite recursion in ~A"
1456 (defn-name (pattern-target pattern))))
1457 (when (null (pattern-crdepth pattern))
1458 (setf (pattern-crdepth pattern) depth)
1459 (check-recursion (defn-child (pattern-target pattern)) depth)
1460 (setf (pattern-crdepth pattern) t)))
1462 (defmethod check-recursion ((pattern %parent) depth)
1463 (check-recursion (pattern-child pattern) depth))
1465 (defmethod check-recursion ((pattern %combination) depth)
1466 (check-recursion (pattern-a pattern) depth)
1467 (check-recursion (pattern-b pattern) depth))
1469 (defmethod check-recursion ((pattern %leaf) depth)
1470 (declare (ignore depth)))
1472 (defmethod check-recursion ((pattern data) depth)
1473 (when (pattern-except pattern)
1474 (check-recursion (pattern-except pattern) depth)))
1477 ;;;; 4.20
1479 ;;; %PARENT
1481 (defmethod fold-not-allowed ((pattern element))
1482 (setf (pattern-child pattern) (fold-not-allowed (pattern-child pattern)))
1483 pattern)
1485 (defmethod fold-not-allowed ((pattern %parent))
1486 (setf (pattern-child pattern) (fold-not-allowed (pattern-child pattern)))
1487 (if (typep (pattern-child pattern) 'not-allowed)
1488 (pattern-child pattern)
1489 pattern))
1491 ;;; %COMBINATION
1493 (defmethod fold-not-allowed ((pattern %combination))
1494 (setf (pattern-a pattern) (fold-not-allowed (pattern-a pattern)))
1495 (setf (pattern-b pattern) (fold-not-allowed (pattern-b pattern)))
1496 pattern)
1498 (defmethod fold-not-allowed ((pattern group))
1499 (call-next-method)
1500 (cond
1501 ;; remove if any child is not allowed
1502 ((typep (pattern-a pattern) 'not-allowed) (pattern-a pattern))
1503 ((typep (pattern-b pattern) 'not-allowed) (pattern-b pattern))
1504 (t pattern)))
1506 (defmethod fold-not-allowed ((pattern interleave))
1507 (call-next-method)
1508 (cond
1509 ;; remove if any child is not allowed
1510 ((typep (pattern-a pattern) 'not-allowed) (pattern-a pattern))
1511 ((typep (pattern-b pattern) 'not-allowed) (pattern-b pattern))
1512 (t pattern)))
1514 (defmethod fold-not-allowed ((pattern choice))
1515 (call-next-method)
1516 (cond
1517 ;; if any child is not allowed, choose the other
1518 ((typep (pattern-a pattern) 'not-allowed) (pattern-b pattern))
1519 ((typep (pattern-b pattern) 'not-allowed) (pattern-a pattern))
1520 (t pattern)))
1522 ;;; LEAF
1524 (defmethod fold-not-allowed ((pattern %leaf))
1525 pattern)
1527 (defmethod fold-not-allowed ((pattern data))
1528 (when (pattern-except pattern)
1529 (setf (pattern-except pattern) (fold-not-allowed (pattern-except pattern)))
1530 (when (typep (pattern-except pattern) 'not-allowed)
1531 (setf (pattern-except pattern) nil)))
1532 pattern)
1534 ;;; REF
1536 (defmethod fold-not-allowed ((pattern ref))
1537 pattern)
1540 ;;;; 4.21
1542 ;;; %PARENT
1544 (defmethod fold-empty ((pattern one-or-more))
1545 (call-next-method)
1546 (if (typep (pattern-child pattern) 'empty)
1547 (pattern-child pattern)
1548 pattern))
1550 (defmethod fold-empty ((pattern %parent))
1551 (setf (pattern-child pattern) (fold-empty (pattern-child pattern)))
1552 pattern)
1554 ;;; %COMBINATION
1556 (defmethod fold-empty ((pattern %combination))
1557 (setf (pattern-a pattern) (fold-empty (pattern-a pattern)))
1558 (setf (pattern-b pattern) (fold-empty (pattern-b pattern)))
1559 pattern)
1561 (defmethod fold-empty ((pattern group))
1562 (call-next-method)
1563 (cond
1564 ;; if any child is empty, choose the other
1565 ((typep (pattern-a pattern) 'empty) (pattern-b pattern))
1566 ((typep (pattern-b pattern) 'empty) (pattern-a pattern))
1567 (t pattern)))
1569 (defmethod fold-empty ((pattern interleave))
1570 (call-next-method)
1571 (cond
1572 ;; if any child is empty, choose the other
1573 ((typep (pattern-a pattern) 'empty) (pattern-b pattern))
1574 ((typep (pattern-b pattern) 'empty) (pattern-a pattern))
1575 (t pattern)))
1577 (defmethod fold-empty ((pattern choice))
1578 (call-next-method)
1579 (if (typep (pattern-b pattern) 'empty)
1580 (cond
1581 ((typep (pattern-a pattern) 'empty)
1582 (pattern-a pattern))
1584 (rotatef (pattern-a pattern) (pattern-b pattern))
1585 pattern))
1586 pattern))
1588 ;;; LEAF
1590 (defmethod fold-empty ((pattern %leaf))
1591 pattern)
1593 (defmethod fold-empty ((pattern data))
1594 (when (pattern-except pattern)
1595 (setf (pattern-except pattern) (fold-empty (pattern-except pattern))))
1596 pattern)
1598 ;;; REF
1600 (defmethod fold-empty ((pattern ref))
1601 pattern)
1604 ;;;; name class overlap
1606 ;;; fixme: memorize this stuff?
1608 (defparameter !uri (string (code-char 1)))
1609 (defparameter !lname "")
1611 (defun classes-overlap-p (nc1 nc2)
1612 (flet ((both-contain (x)
1613 (and (contains nc1 (car x) (cdr x))
1614 (contains nc2 (car x) (cdr x)))))
1615 (or (some #'both-contain (representatives nc1))
1616 (some #'both-contain (representatives nc2)))))
1618 (defmethod representatives ((nc any-name))
1619 (cons (cons !uri !lname)
1620 (if (any-name-except nc)
1621 (representatives (any-name-except nc))
1622 nil)))
1624 (defmethod representatives ((nc ns-name))
1625 (cons (cons (ns-name-uri nc) !lname)
1626 (if (ns-name-except nc)
1627 (representatives (ns-name-except nc))
1628 nil)))
1630 (defmethod representatives ((nc name))
1631 (list (cons (name-uri nc) (name-lname nc))))
1633 (defmethod representatives ((nc name-class-choice))
1634 (nconc (representatives (name-class-choice-a nc))
1635 (representatives (name-class-choice-b nc))))
1638 ;;;; 7.1
1640 (defun finalize-definitions (pattern)
1641 (let ((defns (make-hash-table)))
1642 (labels ((recurse (p)
1643 (cond
1644 ((typep p 'ref)
1645 (let ((target (pattern-target p)))
1646 (unless (gethash target defns)
1647 (setf (gethash target defns) t)
1648 (setf (defn-child target) (recurse (defn-child target))))
1649 (if (typep (defn-child target) 'element)
1651 (copy-pattern-tree (defn-child target)))))
1653 (etypecase p
1654 (data
1655 (when (pattern-except p)
1656 (setf (pattern-except p) (recurse (pattern-except p)))))
1657 (%parent
1658 (setf (pattern-child p) (recurse (pattern-child p))))
1659 (%combination
1660 (setf (pattern-a p) (recurse (pattern-a p)))
1661 (setf (pattern-b p) (recurse (pattern-b p))))
1662 (%leaf))
1663 p))))
1664 (values
1665 (recurse pattern)
1666 (loop
1667 for defn being each hash-key in defns
1668 collect defn)))))
1670 (defun copy-pattern-tree (pattern)
1671 (labels ((recurse (p)
1672 (let ((q (copy-structure p)))
1673 (etypecase p
1674 (data
1675 (when (pattern-except p)
1676 (setf (pattern-except q) (recurse (pattern-except p)))))
1677 (%parent
1678 (setf (pattern-child q) (recurse (pattern-child p))))
1679 (%combination
1680 (setf (pattern-a q) (recurse (pattern-a p)))
1681 (setf (pattern-b q) (recurse (pattern-b p))))
1682 ((or %leaf ref)))
1683 q)))
1684 (recurse pattern)))
1686 (defparameter *in-attribute-p* nil)
1687 (defparameter *in-one-or-more-p* nil)
1688 (defparameter *in-one-or-more//group-or-interleave-p* nil)
1689 (defparameter *in-list-p* nil)
1690 (defparameter *in-data-except-p* nil)
1691 (defparameter *in-start-p* nil)
1693 (defun check-start-restrictions (pattern)
1694 (let ((*in-start-p* t))
1695 (check-restrictions pattern)))
1697 (defun content-type-max (a b)
1698 (if (and a b)
1699 (cond
1700 ((eq a :empty) b)
1701 ((eq b :empty) a)
1702 ((eq a :complex) b)
1703 (:simple))
1704 nil))
1706 (defun groupable-max (a b)
1707 (if (or (eq a :empty)
1708 (eq b :empty)
1709 (and (eq a :complex)
1710 (eq b :complex)))
1711 (content-type-max a b)
1712 nil))
1714 (defun assert-name-class-finite (nc)
1715 (etypecase nc
1716 ((or any-name ns-name)
1717 (rng-error nil "infinite attribute name class outside of one-or-more"))
1718 (name)
1719 (name-class-choice
1720 (assert-name-class-finite (name-class-choice-a nc))
1721 (assert-name-class-finite (name-class-choice-b nc)))))
1723 (defmethod check-restrictions ((pattern attribute))
1724 (when *in-attribute-p*
1725 (rng-error nil "nested attribute not allowed"))
1726 (when *in-one-or-more//group-or-interleave-p*
1727 (rng-error nil "attribute not allowed in oneOrMore//group, oneOrMore//interleave"))
1728 (when *in-list-p*
1729 (rng-error nil "attribute in list not allowed"))
1730 (when *in-data-except-p*
1731 (rng-error nil "attribute in data/except not allowed"))
1732 (when *in-start-p*
1733 (rng-error nil "attribute in start not allowed"))
1734 (let ((*in-attribute-p* t))
1735 (unless *in-one-or-more-p*
1736 (assert-name-class-finite (pattern-name pattern)))
1737 (values (if (check-restrictions (pattern-child pattern))
1738 :empty
1739 nil)
1740 (list (pattern-name pattern))
1741 nil)))
1743 (defmethod check-restrictions ((pattern ref))
1744 (when *in-attribute-p*
1745 (rng-error nil "ref in attribute not allowed"))
1746 (when *in-list-p*
1747 (rng-error nil "ref in list not allowed"))
1748 (when *in-data-except-p*
1749 (rng-error nil "ref in data/except not allowed"))
1750 (values :complex
1752 (list (pattern-name (defn-child (pattern-target pattern))))
1753 nil))
1755 (defmethod check-restrictions ((pattern one-or-more))
1756 (when *in-data-except-p*
1757 (rng-error nil "oneOrMore in data/except not allowed"))
1758 (when *in-start-p*
1759 (rng-error nil "one-or-more in start not allowed"))
1760 (let* ((*in-one-or-more-p* t))
1761 (multiple-value-bind (x a e textp)
1762 (check-restrictions (pattern-child pattern))
1763 (values (groupable-max x x) a e textp))))
1765 (defmethod check-restrictions ((pattern group))
1766 (when *in-data-except-p*
1767 (rng-error nil "group in data/except not allowed"))
1768 (when *in-start-p*
1769 (rng-error nil "group in start not allowed"))
1770 (let ((*in-one-or-more//group-or-interleave-p*
1771 *in-one-or-more-p*))
1772 (multiple-value-bind (x a e tp) (check-restrictions (pattern-a pattern))
1773 (multiple-value-bind (y b f tq) (check-restrictions (pattern-b pattern))
1774 (dolist (nc1 a)
1775 (dolist (nc2 b)
1776 (when (classes-overlap-p nc1 nc2)
1777 (rng-error nil "attribute name overlap in group: ~A ~A"
1778 nc1 nc2))))
1779 (values (groupable-max x y)
1780 (append a b)
1781 (append e f)
1782 (or tp tq))))))
1784 (defmethod check-restrictions ((pattern interleave))
1785 (when *in-list-p*
1786 (rng-error nil "interleave in list not allowed"))
1787 (when *in-data-except-p*
1788 (rng-error nil "interleave in data/except not allowed"))
1789 (when *in-start-p*
1790 (rng-error nil "interleave in start not allowed"))
1791 (let ((*in-one-or-more//group-or-interleave-p*
1792 *in-one-or-more-p*))
1793 (multiple-value-bind (x a e tp) (check-restrictions (pattern-a pattern))
1794 (multiple-value-bind (y b f tq) (check-restrictions (pattern-b pattern))
1795 (dolist (nc1 a)
1796 (dolist (nc2 b)
1797 (when (classes-overlap-p nc1 nc2)
1798 (rng-error nil "attribute name overlap in interleave: ~A ~A"
1799 nc1 nc2))))
1800 (dolist (nc1 e)
1801 (dolist (nc2 f)
1802 (when (classes-overlap-p nc1 nc2)
1803 (rng-error nil "element name overlap in interleave: ~A ~A"
1804 nc1 nc2))))
1805 (when (and tp tq)
1806 (rng-error nil "multiple text permitted by interleave"))
1807 (values (groupable-max x y)
1808 (append a b)
1809 (append e f)
1810 (or tp tq))))))
1812 (defmethod check-restrictions ((pattern choice))
1813 (multiple-value-bind (x a e tp) (check-restrictions (pattern-a pattern))
1814 (multiple-value-bind (y b f tq) (check-restrictions (pattern-b pattern))
1815 (values (content-type-max x y)
1816 (append a b)
1817 (append e f)
1818 (or tp tq)))))
1820 (defmethod check-restrictions ((pattern list-pattern))
1821 (when *in-list-p*
1822 (rng-error nil "nested list not allowed"))
1823 (when *in-data-except-p*
1824 (rng-error nil "list in data/except not allowed"))
1825 (let ((*in-list-p* t))
1826 (check-restrictions (pattern-child pattern)))
1827 (when *in-start-p*
1828 (rng-error nil "list in start not allowed"))
1829 :simple)
1831 (defmethod check-restrictions ((pattern text))
1832 (when *in-list-p*
1833 (rng-error nil "text in list not allowed"))
1834 (when *in-data-except-p*
1835 (rng-error nil "text in data/except not allowed"))
1836 (when *in-start-p*
1837 (rng-error nil "text in start not allowed"))
1838 (values :complex nil nil t))
1840 (defmethod check-restrictions ((pattern data))
1841 (when *in-start-p*
1842 (rng-error nil "data in start not allowed"))
1843 (when (pattern-except pattern)
1844 (let ((*in-data-except-p* t))
1845 (check-restrictions (pattern-except pattern))))
1846 :simple)
1848 (defmethod check-restrictions ((pattern value))
1849 (when *in-start-p*
1850 (rng-error nil "value in start not allowed"))
1851 :simple)
1853 (defmethod check-restrictions ((pattern empty))
1854 (when *in-data-except-p*
1855 (rng-error nil "empty in data/except not allowed"))
1856 (when *in-start-p*
1857 (rng-error nil "empty in start not allowed"))
1858 :empty)
1860 (defmethod check-restrictions ((pattern element))
1861 (unless (check-restrictions (pattern-child pattern))
1862 (rng-error nil "restrictions on string sequences violated")))
1864 (defmethod check-restrictions ((pattern not-allowed))
1865 nil)