2 // Commons.Xml.Relaxng.Derivative.RdpPatterns.cs
5 // Atsushi Enomoto <ginga@kit.hi-ho.ne.jp>
7 // 2003 Atsushi Enomoto "No rights reserved."
9 // Copyright (c) 2004 Novell Inc.
10 // All rights reserved
14 // Permission is hereby granted, free of charge, to any person obtaining
15 // a copy of this software and associated documentation files (the
16 // "Software"), to deal in the Software without restriction, including
17 // without limitation the rights to use, copy, modify, merge, publish,
18 // distribute, sublicense, and/or sell copies of the Software, and to
19 // permit persons to whom the Software is furnished to do so, subject to
20 // the following conditions:
22 // The above copyright notice and this permission notice shall be
23 // included in all copies or substantial portions of the Software.
25 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35 using System.Collections;
37 using Commons.Xml.Relaxng;
39 using LabelList = System.Collections.Hashtable;
42 namespace Commons.Xml.Relaxng.Derivative
44 public delegate RdpPattern RdpApplyAfterHandler (RdpPattern p);
46 // abstract Pattern. Note that in README the classes in this namespace
47 // is explicitly written as not for public use (and hidden in monodoc
49 public abstract class RdpPattern
51 internal bool nullableComputed;
52 internal bool isNullable;
53 Hashtable patternPool;
55 internal string debug ()
57 return RdpUtil.DebugRdpPattern (this, new Hashtable ());
60 public abstract RelaxngPatternType PatternType { get; }
62 public abstract RdpContentType ContentType { get; }
64 private Hashtable setupTable (Type type, RdpPattern p)
66 if (patternPool == null) // could be null for RdpElement etc.
67 patternPool = new Hashtable ();
69 Hashtable typePool = (Hashtable) patternPool [type];
70 if (typePool == null) {
71 typePool = new Hashtable ();
72 patternPool [type] = typePool;
74 Hashtable pTable = (Hashtable) typePool [p];
76 pTable = new Hashtable ();
77 typePool [p] = pTable;
82 internal RdpFlip MakeFlip (RdpBinaryFunction func, RdpPattern p)
84 if (patternPool == null) // could be null for RdpElement etc.
85 patternPool = new Hashtable ();
87 // Though this method takes function argument, all
88 // p1 callers have different pattern types, so we don't
89 // have to distinguish tables by func.
91 Hashtable table = patternPool [func] as Hashtable;
93 table = new Hashtable ();
94 patternPool [func] = table;
96 RdpFlip f = table [p] as RdpFlip;
99 f = new RdpFlip (func, p);
104 public RdpChoice MakeChoiceLeaf (RdpPattern p)
106 if (patternPool == null) // could be null for RdpElement etc.
107 patternPool = new Hashtable ();
108 Hashtable leaves = (Hashtable) patternPool [typeof (RdpEmpty)];
109 if (leaves == null) {
110 leaves = new Hashtable ();
111 patternPool [typeof (RdpEmpty)] = leaves;
113 RdpChoice leaf = leaves [p] as RdpChoice;
115 leaf = new RdpChoice (RdpEmpty.Instance, p);
116 leaf.setInternTable (patternPool);
122 public RdpPattern MakeChoice (RdpPattern p1, RdpPattern p2)
124 if (p1.PatternType == RelaxngPatternType.NotAllowed)
126 if (p2.PatternType == RelaxngPatternType.NotAllowed)
130 // choice-leaves support
131 if (p1.PatternType == RelaxngPatternType.Empty)
132 return MakeChoiceLeaf (p2);
133 if (p2.PatternType == RelaxngPatternType.Empty)
134 return MakeChoiceLeaf (p1);
136 if (p1.GetHashCode () > p2.GetHashCode ()) {
142 Hashtable p1Table = setupTable (typeof (RdpChoice), p1);
143 if (p1Table [p2] == null) {
144 RdpChoice c = new RdpChoice (p1, p2);
145 c.setInternTable (this.patternPool);
148 return (RdpChoice) p1Table [p2];
151 public RdpPattern MakeGroup (RdpPattern p1, RdpPattern p2)
153 if (p1.PatternType == RelaxngPatternType.Empty)
156 Hashtable p1Table = setupTable (typeof (RdpGroup), p1);
157 if (p1Table [p2] == null) {
158 RdpGroup g = new RdpGroup (p1, p2);
159 g.setInternTable (this.patternPool);
162 return (RdpGroup) p1Table [p2];
165 public RdpInterleave MakeInterleave (RdpPattern p1, RdpPattern p2)
167 if (p1.GetHashCode () > p2.GetHashCode ()) {
173 Hashtable p1Table = setupTable (typeof (RdpInterleave), p1);
174 if (p1Table [p2] == null) {
175 RdpInterleave i = new RdpInterleave (p1, p2);
176 i.setInternTable (this.patternPool);
179 return (RdpInterleave) p1Table [p2];
182 public RdpAfter MakeAfter (RdpPattern p1, RdpPattern p2)
184 Hashtable p1Table = setupTable (typeof (RdpAfter), p1);
185 if (p1Table [p2] == null) {
186 RdpAfter a = new RdpAfter (p1, p2);
187 a.setInternTable (this.patternPool);
190 return (RdpAfter) p1Table [p2];
193 public RdpOneOrMore MakeOneOrMore (RdpPattern p)
195 if (patternPool == null) // could be null for RdpElement etc.
196 patternPool = new Hashtable ();
198 Hashtable pTable = (Hashtable) patternPool [typeof (RdpOneOrMore)];
199 if (pTable == null) {
200 pTable = new Hashtable ();
201 patternPool [typeof (RdpOneOrMore)] = pTable;
203 if (pTable [p] == null) {
204 RdpOneOrMore oom = new RdpOneOrMore (p);
205 oom.setInternTable (patternPool);
208 return (RdpOneOrMore) pTable [p];
211 internal void setInternTable (Hashtable ht)
213 if (this.patternPool != null)
215 this.patternPool = ht;
217 Hashtable pt = ht [GetType ()] as Hashtable;
219 pt = new Hashtable ();
220 ht [GetType ()] = pt;
223 RdpAbstractSingleContent single =
224 this as RdpAbstractSingleContent;
225 if (single != null) {
226 if (pt [single.Child] == null) {
227 pt [single.Child] = this;
228 single.Child.setInternTable (ht);
233 RdpAbstractBinary binary =
234 this as RdpAbstractBinary;
235 if (binary != null) {
236 Hashtable lTable = setupTable (GetType (), binary.LValue);
237 if (lTable [binary.RValue] == null) {
238 lTable [binary.RValue] = this;
239 binary.LValue.setInternTable (ht);
240 binary.RValue.setInternTable (ht);
245 // For rest patterns, only check recursively, without pooling.
246 RdpAttribute attr = this as RdpAttribute;
248 attr.Children.setInternTable (ht);
251 RdpElement el = this as RdpElement;
253 el.Children.setInternTable (ht);
256 RdpDataExcept dex= this as RdpDataExcept;
258 dex.Except.setInternTable (ht);
262 switch (PatternType) {
263 case RelaxngPatternType.Empty:
264 case RelaxngPatternType.NotAllowed:
265 case RelaxngPatternType.Text:
266 case RelaxngPatternType.Data:
267 case RelaxngPatternType.Value:
271 #if REPLACE_IN_ADVANCE
272 throw new InvalidOperationException ();
276 internal abstract void MarkReachableDefs ();
278 internal abstract void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept);
280 // This method is to detect text pattern inside interleave child.
281 internal abstract bool ContainsText ();
283 internal virtual RdpPattern ExpandRef (Hashtable defs)
288 internal virtual RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited)
293 public abstract bool Nullable { get; }
295 internal virtual bool IsTextValueDependent {
296 get { return false; }
299 internal virtual bool IsContextDependent {
300 get { return false; }
303 // fills QName collection
304 public void GetLabels (LabelList elements, LabelList attributes)
306 GetLabels (elements, attributes, false);
309 public abstract void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass);
311 internal void AddNameLabel (LabelList names, RdpNameClass nc)
313 RdpName name = nc as RdpName;
315 XmlQualifiedName qname = new XmlQualifiedName (
316 name.LocalName, name.NamespaceURI);
317 names [qname] = qname;
320 RdpNameClassChoice choice = nc as RdpNameClassChoice;
321 if (choice != null) {
322 AddNameLabel (names, choice.LValue);
323 AddNameLabel (names, choice.RValue);
326 // For NsName and AnyName, do nothing.
330 public virtual RdpPattern TextDeriv (string s, XmlReader reader)
332 return RdpNotAllowed.Instance;
335 internal virtual RdpPattern TextDeriv (string s, XmlReader reader, MemoizationStore memo)
337 return TextDeriv (s, reader);
340 internal virtual RdpPattern EmptyTextDeriv (MemoizationStore memo)
342 return TextDeriv (String.Empty, null, memo);
345 internal virtual RdpPattern TextOnlyDeriv ()
350 internal virtual RdpPattern TextOnlyDeriv (MemoizationStore store)
355 internal virtual RdpPattern MixedTextDeriv ()
357 return RdpNotAllowed.Instance;
360 internal virtual RdpPattern MixedTextDeriv (MemoizationStore memo)
362 return RdpNotAllowed.Instance;
365 public RdpPattern ListDeriv (string [] list, int index, XmlReader reader)
367 return listDerivInternal (list, 0, reader);
370 private RdpPattern listDerivInternal (string [] list, int start, XmlReader reader)
372 if (list.Length <= start)
374 else if (list [start].Length == 0)
375 return listDerivInternal (list, start + 1, reader);
377 return this.TextDeriv (list [start].Trim (RdpUtil.WhitespaceChars), reader).listDerivInternal (list, start + 1, reader);
381 public virtual RdpPattern Choice (RdpPattern p)
383 if (p is RdpNotAllowed)
385 else if (this is RdpNotAllowed)
388 return MakeChoice (this, p);
392 public virtual RdpPattern Group (RdpPattern p)
394 if (p is RdpNotAllowed || this is RdpNotAllowed)
395 return RdpNotAllowed.Instance;
396 else if (p is RdpEmpty)
398 else if (this is RdpEmpty)
401 return MakeGroup (this, p);
404 // Interleave(this, p)
405 public virtual RdpPattern Interleave (RdpPattern p)
407 if (p is RdpNotAllowed || this is RdpNotAllowed)
408 return RdpNotAllowed.Instance;
409 else if (p is RdpEmpty)
411 else if (this is RdpEmpty)
414 return MakeInterleave (this, p);
418 public virtual RdpPattern After (RdpPattern p)
420 if (this is RdpNotAllowed || p is RdpNotAllowed)
421 return RdpNotAllowed.Instance;
423 return MakeAfter (this, p);
427 // applyAfter((f, p1=this), p2)
428 public virtual RdpPattern ApplyAfter (RdpApplyAfterHandler h)
430 throw new Exception ("INTERNAL ERROR: should not happen. This is " + this);
433 // startTagOpenDeriv (this, qname)
434 // startTagOpenDeriv _ qn = NotAllowed (default)
435 public virtual RdpPattern StartTagOpenDeriv (string name, string ns)
437 return RdpNotAllowed.Instance;
440 internal virtual RdpPattern StartTagOpenDeriv (string name, string ns, MemoizationStore memo)
442 return StartTagOpenDeriv (name, ns);
445 // attDeriv(ctx, this, att)
446 // attDeriv _ _ _ = NotAllowed
447 public virtual RdpPattern AttDeriv (string name, string ns, string value, XmlReader reader)
449 return RdpNotAllowed.Instance;
452 public virtual RdpPattern StartAttDeriv (string name, string ns)
454 return RdpNotAllowed.Instance;
457 internal virtual RdpPattern StartAttDeriv (string name, string ns, MemoizationStore memo)
459 return StartAttDeriv (name, ns);
462 public virtual RdpPattern EndAttDeriv ()
464 return RdpNotAllowed.Instance;
467 internal virtual RdpPattern EndAttDeriv (MemoizationStore memo)
469 return EndAttDeriv ();
472 public bool ValueMatch (string s, XmlReader reader)
474 return Nullable && Util.IsWhitespace (s) ||
475 TextDeriv (s, reader).Nullable;
478 public virtual RdpPattern StartTagCloseDeriv ()
483 internal virtual RdpPattern StartTagCloseDeriv (MemoizationStore memo)
485 return StartTagCloseDeriv ();
488 public RdpPattern OneOrMore ()
490 if (PatternType == RelaxngPatternType.NotAllowed)
491 return RdpNotAllowed.Instance;
493 return MakeOneOrMore (this);
496 public virtual RdpPattern EndTagDeriv ()
498 return RdpNotAllowed.Instance;
501 internal virtual RdpPattern EndTagDeriv (MemoizationStore memo)
503 return EndTagDeriv ();
509 public class RdpEmpty : RdpPattern
511 public RdpEmpty () {}
514 instance = new RdpEmpty ();
517 public override bool Nullable {
521 internal override bool IsTextValueDependent {
522 get { return false; }
525 internal override bool IsContextDependent {
526 get { return false; }
529 static RdpEmpty instance;
530 public static RdpEmpty Instance {
531 get { return instance; }
534 public override RelaxngPatternType PatternType {
535 get { return RelaxngPatternType.Empty; }
538 public override RdpContentType ContentType {
539 get { return RdpContentType.Empty; }
542 public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)
547 internal override void MarkReachableDefs ()
552 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
555 throw new RelaxngException ("empty cannot appear under except of a data pattern.");
558 internal override bool ContainsText()
565 public class RdpNotAllowed : RdpPattern
567 public RdpNotAllowed () {}
568 static RdpNotAllowed ()
570 instance = new RdpNotAllowed ();
573 static RdpNotAllowed instance;
574 public static RdpNotAllowed Instance {
575 get { return instance; }
578 public override bool Nullable {
579 get { return false; }
582 internal override bool IsTextValueDependent {
583 get { return false; }
586 internal override bool IsContextDependent {
587 get { return false; }
590 public override RdpPattern ApplyAfter (RdpApplyAfterHandler h)
592 return RdpNotAllowed.Instance;
595 public override RelaxngPatternType PatternType {
596 get { return RelaxngPatternType.NotAllowed; }
599 public override RdpContentType ContentType {
600 get { return RdpContentType.Empty; }
603 internal override void MarkReachableDefs ()
608 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
613 internal override bool ContainsText()
618 public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)
620 // FIXME: Supposed to clear something here?
625 public class RdpText : RdpPattern
627 static RdpText instance;
628 public static RdpText Instance {
629 get { return instance; }
635 instance = new RdpText ();
638 public override bool Nullable {
642 internal override bool IsTextValueDependent {
643 get { return false; }
646 internal override bool IsContextDependent {
647 get { return false; }
650 public override RelaxngPatternType PatternType {
651 get { return RelaxngPatternType.Text; }
654 public override RdpContentType ContentType {
655 get { return RdpContentType.Complex; }
658 public override RdpPattern TextDeriv (string s, XmlReader reader)
663 internal override RdpPattern EmptyTextDeriv (MemoizationStore memo)
668 internal override RdpPattern MixedTextDeriv ()
673 internal override RdpPattern MixedTextDeriv (MemoizationStore memo)
678 internal override void MarkReachableDefs ()
683 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
686 throw new RelaxngException ("text is not allowed under a list.");
688 throw new RelaxngException ("text is not allowed under except of a list.");
691 internal override bool ContainsText()
696 public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)
703 public abstract class RdpAbstractBinary : RdpPattern
705 public RdpAbstractBinary (RdpPattern l, RdpPattern r)
712 public RdpPattern LValue {
718 public RdpPattern RValue {
723 RdpContentType computedContentType = RdpContentType.Invalid;
724 public override RdpContentType ContentType {
726 if (computedContentType == RdpContentType.Invalid) {
727 if (l.ContentType == RdpContentType.Empty)
728 computedContentType = r.ContentType;
729 else if (r.ContentType == RdpContentType.Empty)
730 computedContentType = l.ContentType;
731 else if ((l.ContentType & RdpContentType.Simple) != 0 || ((r.ContentType & RdpContentType.Simple) != 0))
732 throw new RelaxngException ("The content type of this group is invalid.");
734 computedContentType = RdpContentType.Complex;
736 return computedContentType;
741 internal override RdpPattern ExpandRef (Hashtable defs)
744 l = l.ExpandRef (defs);
745 r = r.ExpandRef (defs);
750 internal override RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited)
752 if (visited.Contains (this))
754 visited.Add (this, this);
756 if (LValue.PatternType == RelaxngPatternType.NotAllowed ||
757 RValue.PatternType == RelaxngPatternType.NotAllowed) {
759 return RdpNotAllowed.Instance;
760 } else if (LValue.PatternType == RelaxngPatternType.Empty) {
762 return RValue.ReduceEmptyAndNotAllowed (ref result, visited);
763 } else if (RValue.PatternType == RelaxngPatternType.Empty) {
765 return LValue.ReduceEmptyAndNotAllowed (ref result, visited);
767 LValue = LValue.ReduceEmptyAndNotAllowed (ref result, visited);
768 RValue = RValue.ReduceEmptyAndNotAllowed (ref result, visited);
773 internal override void MarkReachableDefs ()
775 l.MarkReachableDefs ();
776 r.MarkReachableDefs ();
779 internal override bool ContainsText()
781 return l.ContainsText () || r.ContainsText ();
784 // 7.3 (group/interleave attribute names) and
785 // part of 7.4 (interleave element names)
786 // FIXME: Actually it should be done against the correct
787 // simplified grammar, expanding all refs.
788 internal void CheckNameOverlap (bool checkElements)
790 if (RdpUtil.NamesOverlap (LValue, RValue, checkElements))
791 throw new RelaxngException ("Duplicate attributes inside a group or an interleave is not allowed.");
797 public class RdpChoice : RdpAbstractBinary
799 public RdpChoice (RdpPattern l, RdpPattern r) : base (l, r)
803 public override bool Nullable {
805 if (!nullableComputed) {
807 LValue.Nullable || RValue.Nullable;
808 nullableComputed = true;
814 bool isTextValueDependentComputed;
815 bool isTextValueDependent;
817 internal override bool IsTextValueDependent {
819 if (!isTextValueDependentComputed) {
820 isTextValueDependent = LValue.IsTextValueDependent || RValue.IsTextValueDependent;
821 isTextValueDependentComputed = true;
823 return isTextValueDependent;
827 bool isContextDependentComputed;
828 bool isContextDependent;
830 internal override bool IsContextDependent {
832 if (!isContextDependentComputed) {
833 isContextDependent = LValue.IsContextDependent || RValue.IsContextDependent;
834 isContextDependentComputed = true;
836 return isContextDependent;
840 public override RelaxngPatternType PatternType {
841 get { return RelaxngPatternType.Choice; }
844 RdpContentType computedContentType = RdpContentType.Invalid;
845 public override RdpContentType ContentType {
847 if (computedContentType == RdpContentType.Invalid) {
848 if (LValue.ContentType == RdpContentType.Simple ||
849 RValue.ContentType == RdpContentType.Simple)
850 computedContentType = RdpContentType.Simple;
852 computedContentType = base.ContentType;
854 return computedContentType;
858 public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)
860 LValue.GetLabels (elements, attributes, collectNameClass);
861 RValue.GetLabels (elements, attributes, collectNameClass);
865 internal override RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited)
867 if (visited.Contains (this))
869 visited.Add (this, this);
871 if (LValue.PatternType == RelaxngPatternType.NotAllowed &&
872 RValue.PatternType == RelaxngPatternType.NotAllowed) {
874 return RdpNotAllowed.Instance;
875 } else if (LValue.PatternType == RelaxngPatternType.NotAllowed) {
877 return RValue.ReduceEmptyAndNotAllowed (ref result, visited);
878 } else if (RValue.PatternType == RelaxngPatternType.NotAllowed) {
880 return LValue.ReduceEmptyAndNotAllowed (ref result, visited);
881 } else if (LValue.PatternType == RelaxngPatternType.Empty &&
882 RValue.PatternType == RelaxngPatternType.Empty) {
884 return RdpEmpty.Instance;
885 } else if (RValue.PatternType == RelaxngPatternType.Empty) {
887 RValue = LValue.ReduceEmptyAndNotAllowed (ref result, visited);
888 LValue = RdpEmpty.Instance;
891 LValue = LValue.ReduceEmptyAndNotAllowed (ref result, visited);
892 RValue = RValue.ReduceEmptyAndNotAllowed (ref result, visited);
897 public override RdpPattern TextDeriv (string s, XmlReader reader)
899 return LValue.TextDeriv (s, reader).Choice (RValue.TextDeriv (s, reader));
902 internal override RdpPattern TextDeriv (string s, XmlReader reader, MemoizationStore memo)
904 return memo.TextDeriv (LValue, s, reader).Choice (memo.TextDeriv (RValue, s, reader));
907 internal override RdpPattern EmptyTextDeriv (MemoizationStore memo)
909 return memo.EmptyTextDeriv (LValue)
910 .Choice (memo.EmptyTextDeriv (RValue));
913 internal override RdpPattern TextOnlyDeriv ()
915 return LValue.TextOnlyDeriv ().Choice (
916 RValue.TextOnlyDeriv ());
919 internal override RdpPattern TextOnlyDeriv (MemoizationStore memo)
921 return memo.TextOnlyDeriv (LValue).Choice (
922 memo.TextOnlyDeriv (RValue));
925 internal override RdpPattern MixedTextDeriv ()
927 return LValue.MixedTextDeriv ().Choice (
928 RValue.MixedTextDeriv ());
931 internal override RdpPattern MixedTextDeriv (MemoizationStore memo)
933 return memo.MixedTextDeriv (LValue).Choice (
934 memo.MixedTextDeriv (RValue));
937 public override RdpPattern ApplyAfter (RdpApplyAfterHandler handler)
939 // return handler (LValue).Choice (handler (RValue));
940 return LValue.ApplyAfter (handler).Choice (RValue.ApplyAfter (handler));
943 public override RdpPattern StartTagOpenDeriv (string name, string ns)
946 return RdpUtil.Choice (
947 RdpUtil.StartTagOpenDeriv (LValue, qname),
948 RdpUtil.StartTagOpenDeriv (RValue, qname));
950 RdpPattern lDeriv = LValue.StartTagOpenDeriv (name, ns);
951 return lDeriv.Choice (RValue.StartTagOpenDeriv (name, ns));
955 internal override RdpPattern StartTagOpenDeriv (string name, string ns, MemoizationStore memo)
957 RdpPattern lDeriv = memo.StartTagOpenDeriv (LValue, name, ns);
958 return lDeriv.Choice (memo.StartTagOpenDeriv (RValue, name, ns));
961 // attDeriv cx (Choice p1 p2) att =
962 // choice (attDeriv cx p1 att) (attDeriv cx p2 att)
963 public override RdpPattern AttDeriv (string name, string ns, string value, XmlReader reader)
965 return LValue.AttDeriv (name, ns, value, reader)
966 .Choice (RValue.AttDeriv (name, ns, value, reader));
969 public override RdpPattern StartAttDeriv (string name, string ns)
971 RdpPattern lDeriv = LValue.StartAttDeriv (name, ns);
972 return lDeriv.Choice (RValue.StartAttDeriv (name, ns));
975 internal override RdpPattern StartAttDeriv (string name, string ns, MemoizationStore memo)
977 return memo.StartAttDeriv (LValue, name, ns)
978 .Choice (memo.StartAttDeriv (RValue, name, ns));
981 public override RdpPattern EndAttDeriv ()
983 return LValue.EndAttDeriv ().Choice (RValue.EndAttDeriv ());
986 internal override RdpPattern EndAttDeriv (MemoizationStore memo)
988 return memo.EndAttDeriv (LValue).Choice (memo.EndAttDeriv (RValue));
991 // startTagCloseDeriv (Choice p1 p2) =
992 // choice (startTagCloseDeriv p1) (startTagCloseDeriv p2)
993 public override RdpPattern StartTagCloseDeriv ()
995 return LValue.StartTagCloseDeriv ()
996 .Choice (RValue.StartTagCloseDeriv ());
999 internal override RdpPattern StartTagCloseDeriv (MemoizationStore memo)
1001 return memo.StartTagCloseDeriv (LValue)
1002 .Choice (memo.StartTagCloseDeriv (RValue));
1005 public override RdpPattern EndTagDeriv ()
1007 return LValue.EndTagDeriv ().Choice (RValue.EndTagDeriv ());
1010 internal override RdpPattern EndTagDeriv (MemoizationStore memo)
1012 return memo.EndTagDeriv (LValue).Choice (memo.EndTagDeriv (RValue));
1015 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
1017 LValue.CheckConstraints (attribute, oneOrMore, oneOrMoreGroup, oneOrMoreInterleave, list, dataExcept);
1018 RValue.CheckConstraints (attribute, oneOrMore, oneOrMoreGroup, oneOrMoreInterleave, list, dataExcept);
1023 public class RdpInterleave : RdpAbstractBinary
1025 public RdpInterleave (RdpPattern l, RdpPattern r) : base (l, r)
1029 public override bool Nullable {
1031 if (!nullableComputed) {
1033 LValue.Nullable && RValue.Nullable;
1034 nullableComputed = true;
1040 internal override bool IsTextValueDependent {
1041 get { return LValue.IsTextValueDependent || RValue.IsTextValueDependent; }
1044 internal override bool IsContextDependent {
1045 get { return LValue.IsContextDependent || RValue.IsContextDependent; }
1048 public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)
1050 LValue.GetLabels (elements, attributes, collectNameClass);
1051 RValue.GetLabels (elements, attributes, collectNameClass);
1054 internal override RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited)
1056 if (visited.Contains (this))
1058 visited.Add (this, this);
1060 if (LValue.PatternType == RelaxngPatternType.NotAllowed ||
1061 RValue.PatternType == RelaxngPatternType.NotAllowed) {
1063 return RdpNotAllowed.Instance;
1065 LValue = LValue.ReduceEmptyAndNotAllowed (ref result, visited);
1066 RValue = RValue.ReduceEmptyAndNotAllowed (ref result, visited);
1071 public override RdpPattern TextDeriv (string s, XmlReader reader)
1073 return LValue.TextDeriv (s, reader).Interleave (RValue)
1074 .Choice (LValue.Interleave (RValue.TextDeriv (s, reader)));
1077 internal override RdpPattern TextDeriv (string s, XmlReader reader, MemoizationStore memo)
1079 return memo.TextDeriv (LValue, s, reader).Interleave (RValue)
1080 .Choice (LValue.Interleave (memo.TextDeriv (RValue, s, reader)));
1083 internal override RdpPattern EmptyTextDeriv (MemoizationStore memo)
1085 return memo.EmptyTextDeriv (LValue).Interleave (RValue)
1086 .Choice (LValue.Interleave (memo.EmptyTextDeriv (RValue)));
1089 internal override RdpPattern TextOnlyDeriv ()
1091 return LValue.TextOnlyDeriv ().Interleave (
1092 RValue.TextOnlyDeriv ());
1095 internal override RdpPattern TextOnlyDeriv (MemoizationStore memo)
1097 return memo.TextOnlyDeriv (LValue).Interleave (
1098 memo.TextOnlyDeriv (RValue));
1101 internal override RdpPattern MixedTextDeriv ()
1103 return LValue.MixedTextDeriv ().Interleave (RValue).Choice (
1104 LValue.Interleave (RValue.MixedTextDeriv ()));
1107 internal override RdpPattern MixedTextDeriv (MemoizationStore memo)
1109 return memo.MixedTextDeriv (LValue).Interleave (RValue).Choice (
1110 LValue.Interleave (memo.MixedTextDeriv (RValue)));
1113 // => choice (applyAfter (flip interleave p2) (startTagOpenDeriv p1 qn)) (applyAfter (interleave p1) (startTagOpenDeriv p2 qn)
1114 // => p1.startTagOpenDeriv(qn).applyAfter (flip interleave p2).choice (p2.startTagOpenDeriv(qn).applyAfter (interleave p1) )
1115 public override RdpPattern StartTagOpenDeriv (string name, string ns)
1117 RdpPattern handledL = LValue.StartTagOpenDeriv (name, ns);
1118 RdpPattern handledR = RValue.StartTagOpenDeriv (name, ns);
1119 RdpFlip flipL = MakeFlip (RdpUtil.InterleaveFunction, RValue);
1120 RdpPattern choiceL = handledL.ApplyAfter (new RdpApplyAfterHandler (flipL.Apply));
1121 RdpPattern choiceR = handledR.ApplyAfter (new RdpApplyAfterHandler (LValue.Interleave));
1122 return choiceL.Choice (choiceR);
1125 internal override RdpPattern StartTagOpenDeriv (string name, string ns, MemoizationStore memo)
1127 RdpPattern handledL = memo.StartTagOpenDeriv (LValue, name, ns);
1128 RdpPattern handledR = memo.StartTagOpenDeriv (RValue, name, ns);
1129 RdpFlip flipL = MakeFlip (RdpUtil.InterleaveFunction, RValue);
1130 RdpPattern choiceL = handledL.ApplyAfter (new RdpApplyAfterHandler (flipL.Apply));
1131 RdpPattern choiceR = handledR.ApplyAfter (new RdpApplyAfterHandler (LValue.Interleave));
1132 return choiceL.Choice (choiceR);
1135 // attDeriv cx (Interleave p1 p2) att =
1136 // choice (interleave (attDeriv cx p1 att) p2)
1137 // (interleave p1 (attDeriv cx p2 att))
1138 public override RdpPattern AttDeriv (string name, string ns, string value, XmlReader reader)
1140 return LValue.AttDeriv (name, ns, value, reader)
1141 .Interleave (RValue)
1142 .Choice (LValue.Interleave (
1143 RValue.AttDeriv (name, ns, value, reader)));
1146 public override RdpPattern StartAttDeriv (string name, string ns)
1148 RdpPattern handledL = LValue.StartAttDeriv (name, ns);
1149 RdpPattern handledR = RValue.StartAttDeriv (name, ns);
1150 RdpFlip flipL = MakeFlip (RdpUtil.InterleaveFunction, RValue);
1151 RdpPattern choiceL = handledL.ApplyAfter (new RdpApplyAfterHandler (flipL.Apply));
1152 RdpPattern choiceR = handledR.ApplyAfter (new RdpApplyAfterHandler (LValue.Interleave));
1153 return choiceL.Choice (choiceR);
1156 internal override RdpPattern StartAttDeriv (string name, string ns, MemoizationStore memo)
1158 RdpPattern handledL = memo.StartAttDeriv (LValue, name, ns);
1159 RdpPattern handledR = memo.StartAttDeriv (RValue, name, ns);
1160 RdpFlip flipL = MakeFlip (RdpUtil.InterleaveFunction, RValue);
1161 RdpPattern choiceL = handledL.ApplyAfter (new RdpApplyAfterHandler (flipL.Apply));
1162 RdpPattern choiceR = handledR.ApplyAfter (new RdpApplyAfterHandler (LValue.Interleave));
1163 return choiceL.Choice (choiceR);
1166 // startTagCloseDeriv (Interleave p1 p2) =
1167 // interleave (startTagCloseDeriv p1) (startTagCloseDeriv p2)
1168 public override RdpPattern StartTagCloseDeriv ()
1170 return LValue.StartTagCloseDeriv ()
1171 .Interleave (RValue.StartTagCloseDeriv ());
1174 internal override RdpPattern StartTagCloseDeriv (MemoizationStore memo)
1176 return memo.StartTagCloseDeriv (LValue)
1177 .Interleave (memo.StartTagCloseDeriv (RValue));
1180 public override RelaxngPatternType PatternType {
1181 get { return RelaxngPatternType.Interleave; }
1184 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
1187 throw new RelaxngException ("interleave is not allowed under a list.");
1189 throw new RelaxngException ("interleave is not allowed under except of a data.");
1192 LValue.CheckConstraints (attribute, oneOrMore, oneOrMoreGroup, oneOrMore, list, dataExcept);
1193 RValue.CheckConstraints (attribute, oneOrMore, oneOrMoreGroup, oneOrMore, list, dataExcept);
1195 // unique name analysis - 7.3 and part of 7.4
1196 CheckNameOverlap (true);
1198 // (2) text/text prohibited
1199 if (LValue.ContainsText () && RValue.ContainsText ())
1200 throw new RelaxngException ("Both branches of the interleave contains a text pattern.");
1205 public class RdpGroup : RdpAbstractBinary
1207 public RdpGroup (RdpPattern l, RdpPattern r) : base (l, r)
1211 public override bool Nullable {
1213 if (!nullableComputed) {
1215 LValue.Nullable && RValue.Nullable;
1216 nullableComputed = true;
1222 internal override bool IsTextValueDependent {
1223 get { return LValue.IsTextValueDependent || (LValue.Nullable ? RValue.IsTextValueDependent : false); }
1226 internal override bool IsContextDependent {
1227 get { return LValue.IsContextDependent || (LValue.Nullable ? RValue.IsContextDependent : false); }
1230 public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)
1232 LValue.GetLabels (elements, attributes, collectNameClass);
1233 if (LValue.Nullable)
1234 RValue.GetLabels (elements, attributes, collectNameClass);
1236 RValue.GetLabels (null, attributes, collectNameClass);
1239 public override RdpPattern TextDeriv (string s, XmlReader reader)
1241 RdpPattern p = LValue.TextDeriv (s, reader);
1242 p = (p.PatternType == RelaxngPatternType.NotAllowed) ?
1243 p : p.Group (RValue);
1244 return LValue.Nullable ?
1245 p.Choice (RValue.TextDeriv (s, reader)) : p;
1248 internal override RdpPattern TextDeriv (string s, XmlReader reader, MemoizationStore memo)
1250 RdpPattern p = memo.TextDeriv (LValue, s, reader);
1251 p = (p.PatternType == RelaxngPatternType.NotAllowed) ?
1252 p : p.Group (RValue);
1253 return LValue.Nullable ?
1254 p.Choice (memo.TextDeriv (RValue, s, reader)) : p;
1257 internal override RdpPattern EmptyTextDeriv (MemoizationStore memo)
1259 RdpPattern p = memo.EmptyTextDeriv (LValue);
1260 p = p.PatternType == RelaxngPatternType.NotAllowed ?
1261 p : p.Group (RValue);
1262 return LValue.Nullable ?
1263 p.Choice (memo.EmptyTextDeriv (RValue)) : p;
1266 internal override RdpPattern TextOnlyDeriv ()
1268 RdpPattern p = LValue.TextOnlyDeriv ();
1269 return p.PatternType == RelaxngPatternType.NotAllowed ?
1270 p : p.Group (RValue.TextOnlyDeriv ());
1273 internal override RdpPattern TextOnlyDeriv (MemoizationStore memo)
1275 RdpPattern p = memo.TextOnlyDeriv (LValue);
1276 return p.PatternType == RelaxngPatternType.NotAllowed ?
1277 p : p.Group (memo.TextOnlyDeriv (RValue));
1280 internal override RdpPattern MixedTextDeriv ()
1282 RdpPattern p = LValue.MixedTextDeriv ().Group (RValue);
1283 return LValue.Nullable ?
1284 p.Choice (RValue.MixedTextDeriv ()) : p;
1287 internal override RdpPattern MixedTextDeriv (MemoizationStore memo)
1289 RdpPattern p = memo.MixedTextDeriv (LValue).Group (RValue);
1290 return LValue.Nullable ?
1291 p.Choice (memo.MixedTextDeriv (RValue)) : p;
1294 // startTagOpenDeriv (Group p1 p2) qn =
1295 // let x = applyAfter (flip group p2) (startTagOpenDeriv p1 qn)
1296 // in if nullable p1 then
1297 // choice x (startTagOpenDeriv p2 qn)
1300 public override RdpPattern StartTagOpenDeriv (string name, string ns)
1302 RdpPattern handled = LValue.StartTagOpenDeriv (name, ns);
1303 RdpFlip f = MakeFlip (RdpUtil.GroupFunction, RValue);
1304 RdpPattern x = handled.ApplyAfter (new RdpApplyAfterHandler (f.Apply));
1305 if (LValue.Nullable)
1306 return x.Choice (RValue.StartTagOpenDeriv (name, ns));
1311 internal override RdpPattern StartTagOpenDeriv (string name, string ns, MemoizationStore memo)
1313 RdpPattern handled = memo.StartTagOpenDeriv (LValue, name, ns);
1314 RdpFlip f = MakeFlip (RdpUtil.GroupFunction, RValue);
1315 RdpPattern x = handled.ApplyAfter (new RdpApplyAfterHandler (f.Apply));
1316 if (LValue.Nullable)
1317 return x.Choice (memo.StartTagOpenDeriv (RValue, name, ns));
1322 // attDeriv cx (Group p1 p2) att =
1323 // choice (group (attDeriv cx p1 att) p2)
1324 // (group p1 (attDeriv cx p2 att))
1325 public override RdpPattern AttDeriv (string name, string ns, string value, XmlReader reader)
1327 return LValue.AttDeriv (name, ns, value, reader).Group (RValue)
1328 .Choice (LValue.Group (
1329 RValue.AttDeriv (name, ns, value, reader)));
1332 // startAttDeriv (group p1 p2) == startAttDeriv (interleave p1 p2)
1333 public override RdpPattern StartAttDeriv (string name, string ns)
1335 RdpPattern handledL = LValue.StartAttDeriv (name, ns);
1336 RdpPattern handledR = RValue.StartAttDeriv (name, ns);
1337 RdpFlip flipL = MakeFlip (RdpUtil.GroupFunction, RValue);
1338 RdpPattern choiceL = handledL.ApplyAfter (new RdpApplyAfterHandler (flipL.Apply));
1339 RdpPattern choiceR = handledR.ApplyAfter (new RdpApplyAfterHandler (LValue.Group));
1340 return choiceL.Choice (choiceR);
1343 internal override RdpPattern StartAttDeriv (string name, string ns, MemoizationStore memo)
1345 RdpPattern handledL = memo.StartAttDeriv (LValue, name, ns);
1346 RdpPattern handledR = memo.StartAttDeriv (RValue, name, ns);
1347 RdpFlip flipL = MakeFlip (RdpUtil.GroupFunction, RValue);
1348 RdpPattern choiceL = handledL.ApplyAfter (new RdpApplyAfterHandler (flipL.Apply));
1349 RdpPattern choiceR = handledR.ApplyAfter (new RdpApplyAfterHandler (LValue.Group));
1350 return choiceL.Choice (choiceR);
1353 // startTagCloseDeriv (Group p1 p2) =
1354 // group (startTagCloseDeriv p1) (startTagCloseDeriv p2)
1355 public override RdpPattern StartTagCloseDeriv ()
1357 RdpPattern p = LValue.StartTagCloseDeriv ();
1358 return p.PatternType == RelaxngPatternType.NotAllowed ?
1359 p : p.Group (RValue.StartTagCloseDeriv ());
1362 internal override RdpPattern StartTagCloseDeriv (MemoizationStore memo)
1364 RdpPattern p = memo.StartTagCloseDeriv (LValue);
1365 return p.PatternType == RelaxngPatternType.NotAllowed ?
1366 p : p.Group (memo.StartTagCloseDeriv (RValue));
1369 public override RelaxngPatternType PatternType {
1370 get { return RelaxngPatternType.Group; }
1373 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
1376 throw new RelaxngException ("interleave is not allowed under except of a data.");
1378 LValue.CheckConstraints (attribute, oneOrMore, oneOrMore, oneOrMoreInterleave, list, dataExcept);
1379 RValue.CheckConstraints (attribute, oneOrMore, oneOrMore, oneOrMoreInterleave, list, dataExcept);
1382 CheckNameOverlap (false);
1386 public abstract class RdpAbstractSingleContent : RdpPattern
1391 internal override RdpPattern ExpandRef (Hashtable defs)
1394 child = child.ExpandRef (defs);
1398 public RdpAbstractSingleContent (RdpPattern p)
1403 public RdpPattern Child {
1404 get { return child; }
1405 set { child = value; }
1408 internal override void MarkReachableDefs ()
1410 child.MarkReachableDefs ();
1413 internal override bool ContainsText()
1415 return child.ContainsText ();
1420 public class RdpOneOrMore : RdpAbstractSingleContent
1422 public RdpOneOrMore (RdpPattern p) : base (p)
1426 public override RelaxngPatternType PatternType {
1427 get { return RelaxngPatternType.OneOrMore; }
1430 public override RdpContentType ContentType {
1432 if (Child.ContentType == RdpContentType.Simple)
1433 throw new RelaxngException ("Invalid content type was found.");
1434 return Child.ContentType;
1438 public override bool Nullable {
1439 get { return Child.Nullable; }
1442 internal override bool IsTextValueDependent {
1443 get { return Child.IsTextValueDependent; }
1446 internal override bool IsContextDependent {
1447 get { return Child.IsContextDependent; }
1450 public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)
1452 Child.GetLabels (elements, attributes, collectNameClass);
1455 internal override RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited)
1457 if (visited.Contains (this))
1459 visited.Add (this, this);
1461 if (Child.PatternType == RelaxngPatternType.NotAllowed) {
1463 return RdpNotAllowed.Instance;
1464 } else if (Child.PatternType == RelaxngPatternType.Empty)
1465 return RdpEmpty.Instance;
1467 Child = Child.ReduceEmptyAndNotAllowed (ref result, visited);
1472 public override RdpPattern TextDeriv (string s, XmlReader reader)
1474 RdpPattern p = Child.TextDeriv (s, reader);
1475 return p.PatternType == RelaxngPatternType.NotAllowed ?
1476 p : p.Group (this.Choice (RdpEmpty.Instance));
1479 internal override RdpPattern TextDeriv (string s, XmlReader reader, MemoizationStore memo)
1481 RdpPattern p = memo.TextDeriv (Child, s, reader);
1482 return p.PatternType == RelaxngPatternType.NotAllowed ?
1483 p : p.Group (this.Choice (RdpEmpty.Instance));
1486 internal override RdpPattern EmptyTextDeriv (MemoizationStore memo)
1488 RdpPattern p = memo.EmptyTextDeriv (Child);
1489 return p.PatternType == RelaxngPatternType.NotAllowed ?
1490 p : p.Group (this.Choice (RdpEmpty.Instance));
1493 internal override RdpPattern TextOnlyDeriv ()
1495 return Child.TextOnlyDeriv ().OneOrMore ();
1498 internal override RdpPattern TextOnlyDeriv (MemoizationStore memo)
1500 return memo.TextOnlyDeriv (Child).OneOrMore ();
1503 internal override RdpPattern MixedTextDeriv ()
1505 RdpPattern p = Child.MixedTextDeriv ();
1506 return p.PatternType == RelaxngPatternType.NotAllowed ?
1507 p : p.Group (this.Choice (RdpEmpty.Instance));
1510 internal override RdpPattern MixedTextDeriv (MemoizationStore memo)
1512 RdpPattern p = memo.MixedTextDeriv (Child);
1513 return p.PatternType == RelaxngPatternType.NotAllowed ?
1514 p : p.Group (this.Choice (RdpEmpty.Instance));
1517 // attDeriv cx (OneOrMore p) att =
1518 // group (attDeriv cx p att) (choice (OneOrMore p) Empty)
1519 public override RdpPattern AttDeriv (string name, string ns, string value, XmlReader reader)
1521 RdpPattern p = Child.AttDeriv (name, ns, value, reader);
1522 return p.PatternType == RelaxngPatternType.NotAllowed ?
1523 p : p.Group (Choice (RdpEmpty.Instance));
1526 // startTagOpenDeriv (OneOrMore p) qn =
1527 // applyAfter (flip group (choice (OneOrMore p) Empty))
1528 // (startTagOpenDeriv p qn)
1529 public override RdpPattern StartTagOpenDeriv (string name, string ns)
1531 RdpPattern rest = RdpEmpty.Instance.Choice (Child.OneOrMore ());
1532 RdpPattern handled = Child.StartTagOpenDeriv (name, ns);
1533 RdpFlip f = MakeFlip (RdpUtil.GroupFunction, rest);
1534 return handled.ApplyAfter (new RdpApplyAfterHandler (f.Apply));
1537 internal override RdpPattern StartTagOpenDeriv (string name, string ns, MemoizationStore memo)
1539 RdpPattern rest = RdpEmpty.Instance.Choice (Child.OneOrMore ());
1540 RdpPattern handled = memo.StartTagOpenDeriv (Child, name, ns);
1541 RdpFlip f = MakeFlip (RdpUtil.GroupFunction, rest);
1542 return handled.ApplyAfter (new RdpApplyAfterHandler (f.Apply));
1545 public override RdpPattern StartAttDeriv (string name, string ns)
1547 RdpPattern rest = RdpEmpty.Instance.Choice (Child.OneOrMore ());
1548 RdpPattern handled = Child.StartAttDeriv (name, ns);
1549 RdpFlip f = MakeFlip (RdpUtil.GroupFunction, rest);
1550 return handled.ApplyAfter (new RdpApplyAfterHandler (f.Apply));
1553 internal override RdpPattern StartAttDeriv (string name, string ns, MemoizationStore memo)
1555 RdpPattern rest = RdpEmpty.Instance.Choice (Child.OneOrMore ());
1556 RdpPattern handled = memo.StartAttDeriv (Child, name, ns);
1557 RdpFlip f = MakeFlip (RdpUtil.GroupFunction, rest);
1558 return handled.ApplyAfter (new RdpApplyAfterHandler (f.Apply));
1561 // startTagCloseDeriv (OneOrMore p) =
1562 // oneOrMore (startTagCloseDeriv p)
1563 public override RdpPattern StartTagCloseDeriv ()
1566 return RdpUtil.OneOrMore (
1567 RdpUtil.StartTagCloseDeriv (children));
1569 return Child.StartTagCloseDeriv ().OneOrMore ();
1573 internal override RdpPattern StartTagCloseDeriv (MemoizationStore memo)
1575 return memo.StartTagCloseDeriv (Child).OneOrMore ();
1578 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
1581 throw new RelaxngException ("oneOrMore is not allowed under except of a data.");
1582 this.Child.CheckConstraints (attribute, true, oneOrMoreGroup, oneOrMoreInterleave, list, dataExcept);
1587 public class RdpList : RdpAbstractSingleContent
1589 public RdpList (RdpPattern p) : base (p)
1593 internal override RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited)
1595 if (visited.Contains (this))
1597 visited.Add (this, this);
1599 if (Child.PatternType == RelaxngPatternType.NotAllowed) {
1601 return RdpNotAllowed.Instance;
1603 Child = Child.ReduceEmptyAndNotAllowed (ref result, visited);
1608 public override bool Nullable {
1609 get { return false; }
1612 internal override bool IsTextValueDependent {
1613 get { return true; }
1616 internal override bool IsContextDependent {
1617 get { return Child.IsContextDependent; }
1620 public override RelaxngPatternType PatternType {
1621 get { return RelaxngPatternType.List; }
1624 public override RdpContentType ContentType {
1625 get { return RdpContentType.Simple; }
1628 public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)
1630 Child.GetLabels (elements, attributes, collectNameClass);
1633 public override RdpPattern TextDeriv (string s, XmlReader reader)
1635 s = Util.NormalizeWhitespace (s);
1637 RdpPattern p = Child.ListDeriv (s.Split (RdpUtil.WhitespaceChars), 0, reader);
1639 return RdpEmpty.Instance;
1641 return RdpNotAllowed.Instance;
1644 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
1647 throw new RelaxngException ("list is not allowed uner another list.");
1649 throw new RelaxngException ("list is not allowed under except of a data.");
1650 this.Child.CheckConstraints (attribute, oneOrMore, oneOrMoreGroup, oneOrMoreInterleave, true, dataExcept);
1655 public class RdpData : RdpPattern
1657 public RdpData (RdpDatatype dt)
1663 public RdpDatatype Datatype {
1667 public override bool Nullable {
1668 get { return false; }
1671 internal override bool IsTextValueDependent {
1672 get { return true; }
1675 internal override bool IsContextDependent {
1676 get { return dt.IsContextDependent; }
1679 public override RelaxngPatternType PatternType {
1680 get { return RelaxngPatternType.Data; }
1683 public override RdpContentType ContentType {
1684 get { return RdpContentType.Simple; }
1687 public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)
1692 public override RdpPattern TextDeriv (string s, XmlReader reader)
1694 if (dt.IsAllowed (s, reader))
1695 return RdpEmpty.Instance;
1697 return RdpNotAllowed.Instance;
1700 internal override void MarkReachableDefs ()
1705 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
1710 internal override bool ContainsText()
1717 public class RdpDataExcept : RdpData
1719 public RdpDataExcept (RdpDatatype dt, RdpPattern except)
1722 this.except = except;
1726 public RdpPattern Except {
1727 get { return except; }
1728 set { except = value; }
1731 public override RelaxngPatternType PatternType {
1732 get { return RelaxngPatternType.DataExcept; }
1735 public override RdpContentType ContentType {
1737 RdpContentType c = except.ContentType; // conformance required for except pattern.
1738 return RdpContentType.Simple;
1742 internal override RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited)
1744 if (visited.Contains (this))
1746 visited.Add (this, this);
1748 if (except.PatternType == RelaxngPatternType.NotAllowed) {
1750 return new RdpData (this.Datatype);
1752 except = except.ReduceEmptyAndNotAllowed (ref result, visited);
1757 public override RdpPattern TextDeriv (string s, XmlReader reader)
1759 if (Datatype.IsAllowed (s, reader) && !except.TextDeriv (s, reader).Nullable)
1760 return RdpEmpty.Instance;
1762 return RdpNotAllowed.Instance;
1765 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
1767 this.except.CheckConstraints (attribute, oneOrMore, oneOrMoreGroup, oneOrMoreInterleave, list, true);
1770 internal override bool ContainsText()
1772 return except.ContainsText ();
1777 public class RdpValue : RdpPattern
1779 public RdpValue (RdpDatatype dt, string value)
1786 public RdpDatatype Datatype {
1791 public string Value {
1792 get { return value; }
1795 public override bool Nullable {
1796 get { return false; }
1799 internal override bool IsTextValueDependent {
1800 get { return true; }
1803 internal override bool IsContextDependent {
1804 get { return dt.IsContextDependent; }
1807 public override RelaxngPatternType PatternType {
1808 get { return RelaxngPatternType.Value; }
1811 public override RdpContentType ContentType {
1812 get { return RdpContentType.Simple; }
1815 public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)
1821 RdpPattern cachedPattern;
1823 public override RdpPattern TextDeriv (string s, XmlReader reader)
1825 if (s == cachedValue && !IsContextDependent)
1826 return cachedPattern;
1827 cachedPattern = TextDerivCore (s, reader);
1829 return cachedPattern;
1832 RdpPattern TextDerivCore (string s, XmlReader reader)
1834 if (dt.IsTypeEqual (value, s, reader))
1835 return RdpEmpty.Instance;
1837 return RdpNotAllowed.Instance;
1840 internal override void MarkReachableDefs ()
1845 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
1847 // nothing to be checked
1850 internal override bool ContainsText()
1857 public class RdpAttribute : RdpPattern
1859 public RdpAttribute (RdpNameClass nameClass, RdpPattern p)
1861 this.nameClass = nameClass;
1865 RdpNameClass nameClass;
1866 public RdpNameClass NameClass {
1867 get { return nameClass; }
1870 RdpPattern children;
1871 public RdpPattern Children {
1872 get { return children; }
1873 set { children = value; }
1876 public override bool Nullable {
1877 get { return false; }
1880 internal override bool IsTextValueDependent {
1881 get { return false; }
1884 internal override bool IsContextDependent {
1885 get { return false; }
1888 public override RelaxngPatternType PatternType {
1889 get { return RelaxngPatternType.Attribute; }
1892 public override RdpContentType ContentType {
1893 get { return RdpContentType.Empty; }
1896 public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)
1898 if (attributes != null) {
1899 if (collectNameClass)
1900 attributes [NameClass] = NameClass;
1902 AddNameLabel (attributes, NameClass);
1907 internal override RdpPattern ExpandRef (Hashtable defs)
1911 children = children.ExpandRef (defs);
1916 internal override RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited)
1918 if (visited.Contains (this))
1920 visited.Add (this, this);
1922 if (children.PatternType == RelaxngPatternType.NotAllowed) {
1924 return RdpNotAllowed.Instance;
1926 children = children.ReduceEmptyAndNotAllowed (ref result, visited);
1931 // attDeriv cx (Attribute nc p) (AttributeNode qn s) =
1932 // if contains nc qn && valueMatch cx p s then Empty else NotAllowed
1933 public override RdpPattern AttDeriv (string name, string ns, string value, XmlReader reader)
1935 // If value is null, then does not check ValueMatch.
1937 if (RdpUtil.Contains (this.nameClass, att.QName)
1938 && (value == null || RdpUtil.ValueMatch (ctx, this.children, att.Value)))
1939 return RdpEmpty.Instance;
1941 return RdpNotAllowed.Instance;
1943 if (nameClass.Contains (name, ns) &&
1944 (value == null || children.ValueMatch (value, reader)))
1945 return RdpEmpty.Instance;
1947 return RdpNotAllowed.Instance;
1951 public override RdpPattern StartAttDeriv (string name, string ns)
1953 return nameClass.Contains (name, ns) ?
1954 children.After (RdpEmpty.Instance) : RdpNotAllowed.Instance;
1957 internal override RdpPattern StartAttDeriv (string name, string ns, MemoizationStore memo)
1959 return nameClass.Contains (name, ns) ?
1960 children.After (RdpEmpty.Instance) : RdpNotAllowed.Instance;
1963 // startTagCloseDeriv (Attribute _ _) = NotAllowed
1964 public override RdpPattern StartTagCloseDeriv ()
1966 return RdpNotAllowed.Instance;
1969 internal override RdpPattern StartTagCloseDeriv (MemoizationStore memo)
1971 return RdpNotAllowed.Instance;
1974 internal override void MarkReachableDefs ()
1976 children.MarkReachableDefs ();
1979 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
1982 if (attribute || oneOrMoreGroup || oneOrMoreInterleave || list || dataExcept)
1983 throw new RelaxngException ("Not allowed attribute occurence was specified in the pattern.");
1985 // latter part of 7.3
1986 if (!oneOrMore && NameClass.HasInfiniteName)
1987 throw new RelaxngException ("Attributes that has an infinite name class must be repeatable.");
1989 this.Children.CheckConstraints (true, oneOrMore, false, false, false, false);
1992 internal override bool ContainsText()
1994 // This method is to detect text pattern inside interleave child.
1995 // return children.ContainsText ();
2001 public class RdpElement : RdpPattern
2003 public RdpElement (RdpNameClass nameClass, RdpPattern p)
2005 this.nameClass = nameClass;
2009 RdpNameClass nameClass;
2010 public RdpNameClass NameClass {
2011 get { return nameClass; }
2014 RdpPattern children;
2015 public RdpPattern Children {
2016 get { return children; }
2017 set { children = value; }
2020 public override bool Nullable {
2021 get { return false; }
2024 internal override bool IsTextValueDependent {
2025 get { return false; }
2028 internal override bool IsContextDependent {
2029 get { return false; }
2032 public override RelaxngPatternType PatternType {
2033 get { return RelaxngPatternType.Element; }
2036 bool contentTypeCheckDone;
2037 public override RdpContentType ContentType {
2039 if (!contentTypeCheckDone) {
2040 contentTypeCheckDone = true;
2041 RdpContentType ct = children.ContentType; // conformance required.
2043 return RdpContentType.Complex;
2047 public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)
2049 if (elements != null) {
2050 if (collectNameClass)
2051 elements [NameClass] = NameClass;
2053 AddNameLabel (elements, NameClass);
2059 short expanding; // FIXME: It is totally not required, but there is
2060 // some bugs in simplification and without it it causes infinite loop.
2061 internal override RdpPattern ExpandRef (Hashtable defs)
2065 if (expanding == 100)
2066 throw new RelaxngException (String.Format ("Invalid recursion was found. Name is {0}", nameClass));
2068 children = children.ExpandRef (defs);
2074 internal override RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited)
2076 if (visited.Contains (this))
2078 visited.Add (this, this);
2080 children = children.ReduceEmptyAndNotAllowed (ref result, visited);
2084 internal override RdpPattern TextOnlyDeriv ()
2086 return RdpNotAllowed.Instance;
2089 internal override RdpPattern TextOnlyDeriv (MemoizationStore memo)
2091 return RdpNotAllowed.Instance;
2094 public override RdpPattern StartTagOpenDeriv (string name, string ns)
2097 if (RdpUtil.Contains (this.nameClass, qname))
2098 return RdpUtil.After (this.Children, RdpEmpty.Instance);
2100 return RdpNotAllowed.Instance;
2102 return nameClass.Contains (name, ns) ?
2103 children.After (RdpEmpty.Instance) :
2104 RdpNotAllowed.Instance;
2108 internal override RdpPattern StartTagOpenDeriv (string name, string ns, MemoizationStore memo)
2110 return nameClass.Contains (name, ns) ?
2111 children.After (RdpEmpty.Instance) :
2112 RdpNotAllowed.Instance;
2115 internal override void MarkReachableDefs ()
2117 children.MarkReachableDefs ();
2120 bool constraintsChecked;
2121 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
2123 if (constraintsChecked)
2125 constraintsChecked = true;
2126 if (attribute || list || dataExcept)
2127 throw new RelaxngException ("Not allowed element occurence was specified in the pattern.");
2128 this.Children.CheckConstraints (false, oneOrMore, oneOrMoreGroup, oneOrMoreInterleave, false, false);
2131 internal override bool ContainsText()
2133 return children.ContainsText ();
2138 public class RdpAfter : RdpAbstractBinary
2140 public RdpAfter (RdpPattern l, RdpPattern r) : base (l, r)
2144 public override bool Nullable {
2145 get { return false; }
2148 internal override bool IsTextValueDependent {
2149 get { return LValue.IsTextValueDependent; }
2152 internal override bool IsContextDependent {
2153 get { return LValue.IsContextDependent; }
2156 public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)
2158 LValue.GetLabels (elements, attributes, collectNameClass);
2161 public override RdpPattern TextDeriv (string s, XmlReader reader)
2163 return LValue.TextDeriv (s, reader).After (RValue);
2166 internal override RdpPattern TextDeriv (string s, XmlReader reader, MemoizationStore memo)
2168 return memo.TextDeriv (LValue, s, reader).After (RValue);
2171 internal override RdpPattern EmptyTextDeriv (MemoizationStore memo)
2173 return memo.EmptyTextDeriv (LValue).After (RValue);
2176 internal override RdpPattern TextOnlyDeriv ()
2178 return LValue.TextOnlyDeriv ().After (RValue);
2181 internal override RdpPattern TextOnlyDeriv (MemoizationStore memo)
2183 return memo.TextOnlyDeriv (LValue).After (RValue);
2186 internal override RdpPattern MixedTextDeriv ()
2188 return LValue.MixedTextDeriv ().After (RValue);
2191 internal override RdpPattern MixedTextDeriv (MemoizationStore memo)
2193 return memo.MixedTextDeriv (LValue).After (RValue);
2196 // startTagOpenDeriv (After p1 p2) qn =
2197 // applyAfter (flip after p2) (startTagOpenDeriv p1 qn)
2198 public override RdpPattern StartTagOpenDeriv (string name, string ns)
2200 RdpPattern handled = LValue.StartTagOpenDeriv (name, ns);
2201 RdpFlip f = MakeFlip (RdpUtil.AfterFunction, RValue);
2202 return handled.ApplyAfter (new RdpApplyAfterHandler (
2206 internal override RdpPattern StartTagOpenDeriv (string name, string ns, MemoizationStore memo)
2208 RdpPattern handled = memo.StartTagOpenDeriv (LValue, name, ns);
2209 RdpFlip f = MakeFlip (RdpUtil.AfterFunction, RValue);
2210 return handled.ApplyAfter (new RdpApplyAfterHandler (
2214 public override RdpPattern ApplyAfter (RdpApplyAfterHandler handler)
2216 return LValue.After (handler (RValue));
2219 // attDeriv cx (After p1 p2) att =
2220 // after (attDeriv cx p1 att) p2
2221 public override RdpPattern AttDeriv (string name, string ns, string value, XmlReader reader)
2223 return LValue.AttDeriv (name, ns, value, reader).After (RValue);
2226 public override RdpPattern StartAttDeriv (string name, string ns)
2228 RdpPattern handled = LValue.StartAttDeriv (name, ns);
2229 RdpFlip f = MakeFlip (RdpUtil.AfterFunction, RValue);
2230 return handled.ApplyAfter (new RdpApplyAfterHandler (
2234 internal override RdpPattern StartAttDeriv (string name, string ns, MemoizationStore memo)
2236 RdpPattern handled = memo.StartAttDeriv (LValue, name, ns);
2237 RdpFlip f = MakeFlip (RdpUtil.AfterFunction, RValue);
2238 return handled.ApplyAfter (new RdpApplyAfterHandler (
2242 public override RdpPattern EndAttDeriv ()
2244 return LValue.Nullable ? RValue : RdpNotAllowed.Instance;
2247 public override RdpPattern StartTagCloseDeriv ()
2249 return LValue.StartTagCloseDeriv ().After (RValue);
2252 internal override RdpPattern StartTagCloseDeriv (MemoizationStore memo)
2254 return memo.StartTagCloseDeriv (LValue).After (RValue);
2257 public override RdpPattern EndTagDeriv ()
2259 return LValue.Nullable ? RValue : RdpNotAllowed.Instance;
2262 public override RelaxngPatternType PatternType {
2263 get { return RelaxngPatternType.After; }
2266 internal override void MarkReachableDefs ()
2268 throw new InvalidOperationException ();
2271 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
2273 throw new InvalidOperationException ();
2276 internal override bool ContainsText ()
2278 throw new InvalidOperationException ();