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 public static readonly RdpPattern Anything;
55 RdpPattern anyAtts = new RdpList (new RdpAttribute (RdpAnyName.Instance, RdpText.Instance));
56 RdpElement anyElement = new RdpElement (RdpAnyName.Instance, null);
57 Anything = new RdpChoice (RdpEmpty.Instance, new RdpChoice (anyAtts, new RdpChoice (RdpText.Instance, new RdpList (anyElement))));
58 anyElement.Children = Anything;
61 internal bool nullableComputed;
62 internal bool isNullable;
63 Hashtable patternPool;
65 internal string debug ()
67 return RdpUtil.DebugRdpPattern (this, new Hashtable ());
70 public abstract RelaxngPatternType PatternType { get; }
72 public abstract RdpContentType ContentType { get; }
74 private Hashtable setupTable (Type type, RdpPattern p)
76 if (patternPool == null) // could be null for RdpElement etc.
77 patternPool = new Hashtable ();
79 Hashtable typePool = (Hashtable) patternPool [type];
80 if (typePool == null) {
81 typePool = new Hashtable ();
82 patternPool [type] = typePool;
84 Hashtable pTable = (Hashtable) typePool [p];
86 pTable = new Hashtable ();
87 typePool [p] = pTable;
92 internal RdpFlip MakeFlip (RdpBinaryFunction func, RdpPattern p)
94 if (patternPool == null) // could be null for RdpElement etc.
95 patternPool = new Hashtable ();
97 // Though this method takes function argument, all
98 // p1 callers have different pattern types, so we don't
99 // have to distinguish tables by func.
101 Hashtable table = patternPool [func] as Hashtable;
103 table = new Hashtable ();
104 patternPool [func] = table;
106 RdpFlip f = table [p] as RdpFlip;
109 f = new RdpFlip (func, p);
114 public RdpChoice MakeChoiceLeaf (RdpPattern p)
116 if (patternPool == null) // could be null for RdpElement etc.
117 patternPool = new Hashtable ();
118 Hashtable leaves = (Hashtable) patternPool [typeof (RdpEmpty)];
119 if (leaves == null) {
120 leaves = new Hashtable ();
121 patternPool [typeof (RdpEmpty)] = leaves;
123 RdpChoice leaf = leaves [p] as RdpChoice;
125 leaf = new RdpChoice (RdpEmpty.Instance, p);
126 leaf.setInternTable (patternPool);
132 public RdpPattern MakeChoice (RdpPattern p1, RdpPattern p2)
134 if (p1.PatternType == RelaxngPatternType.NotAllowed)
136 if (p2.PatternType == RelaxngPatternType.NotAllowed)
140 // choice-leaves support
141 if (p1.PatternType == RelaxngPatternType.Empty)
142 return MakeChoiceLeaf (p2);
143 if (p2.PatternType == RelaxngPatternType.Empty)
144 return MakeChoiceLeaf (p1);
146 if (p1.GetHashCode () > p2.GetHashCode ()) {
152 Hashtable p1Table = setupTable (typeof (RdpChoice), p1);
153 if (p1Table [p2] == null) {
154 RdpChoice c = new RdpChoice (p1, p2);
155 c.setInternTable (this.patternPool);
158 return (RdpChoice) p1Table [p2];
161 public RdpPattern MakeGroup (RdpPattern p1, RdpPattern p2)
163 if (p1.PatternType == RelaxngPatternType.Empty)
166 Hashtable p1Table = setupTable (typeof (RdpGroup), p1);
167 if (p1Table [p2] == null) {
168 RdpGroup g = new RdpGroup (p1, p2);
169 g.setInternTable (this.patternPool);
172 return (RdpGroup) p1Table [p2];
175 public RdpInterleave MakeInterleave (RdpPattern p1, RdpPattern p2)
177 if (p1.GetHashCode () > p2.GetHashCode ()) {
183 Hashtable p1Table = setupTable (typeof (RdpInterleave), p1);
184 if (p1Table [p2] == null) {
185 RdpInterleave i = new RdpInterleave (p1, p2);
186 i.setInternTable (this.patternPool);
189 return (RdpInterleave) p1Table [p2];
192 public RdpAfter MakeAfter (RdpPattern p1, RdpPattern p2)
194 Hashtable p1Table = setupTable (typeof (RdpAfter), p1);
195 if (p1Table [p2] == null) {
196 RdpAfter a = new RdpAfter (p1, p2);
197 a.setInternTable (this.patternPool);
200 return (RdpAfter) p1Table [p2];
203 public RdpOneOrMore MakeOneOrMore (RdpPattern p)
205 if (patternPool == null) // could be null for RdpElement etc.
206 patternPool = new Hashtable ();
208 Hashtable pTable = (Hashtable) patternPool [typeof (RdpOneOrMore)];
209 if (pTable == null) {
210 pTable = new Hashtable ();
211 patternPool [typeof (RdpOneOrMore)] = pTable;
213 if (pTable [p] == null) {
214 RdpOneOrMore oom = new RdpOneOrMore (p);
215 oom.setInternTable (patternPool);
218 return (RdpOneOrMore) pTable [p];
221 internal void setInternTable (Hashtable ht)
223 if (this.patternPool != null)
225 this.patternPool = ht;
227 Hashtable pt = ht [GetType ()] as Hashtable;
229 pt = new Hashtable ();
230 ht [GetType ()] = pt;
233 RdpAbstractSingleContent single =
234 this as RdpAbstractSingleContent;
235 if (single != null) {
236 if (pt [single.Child] == null) {
237 pt [single.Child] = this;
238 single.Child.setInternTable (ht);
243 RdpAbstractBinary binary =
244 this as RdpAbstractBinary;
245 if (binary != null) {
246 Hashtable lTable = setupTable (GetType (), binary.LValue);
247 if (lTable [binary.RValue] == null) {
248 lTable [binary.RValue] = this;
249 binary.LValue.setInternTable (ht);
250 binary.RValue.setInternTable (ht);
255 // For rest patterns, only check recursively, without pooling.
256 RdpAttribute attr = this as RdpAttribute;
258 attr.Children.setInternTable (ht);
261 RdpElement el = this as RdpElement;
263 el.Children.setInternTable (ht);
266 RdpDataExcept dex= this as RdpDataExcept;
268 dex.Except.setInternTable (ht);
272 switch (PatternType) {
273 case RelaxngPatternType.Empty:
274 case RelaxngPatternType.NotAllowed:
275 case RelaxngPatternType.Text:
276 case RelaxngPatternType.Data:
277 case RelaxngPatternType.Value:
281 #if REPLACE_IN_ADVANCE
282 throw new InvalidOperationException ();
286 internal abstract void MarkReachableDefs ();
288 internal abstract void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept);
290 // This method is to detect text pattern inside interleave child.
291 internal abstract bool ContainsText ();
293 internal virtual RdpPattern ExpandRef (Hashtable defs)
298 internal virtual RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited)
303 public abstract bool Nullable { get; }
305 internal virtual bool IsTextValueDependent {
306 get { return false; }
309 internal virtual bool IsContextDependent {
310 get { return false; }
313 // fills QName collection
314 public void GetLabels (LabelList elements, LabelList attributes)
316 GetLabels (elements, attributes, false);
319 public abstract void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass);
321 internal void AddNameLabel (LabelList names, RdpNameClass nc)
323 RdpName name = nc as RdpName;
325 XmlQualifiedName qname = new XmlQualifiedName (
326 name.LocalName, name.NamespaceURI);
327 names [qname] = qname;
330 RdpNameClassChoice choice = nc as RdpNameClassChoice;
331 if (choice != null) {
332 AddNameLabel (names, choice.LValue);
333 AddNameLabel (names, choice.RValue);
336 // For NsName and AnyName, do nothing.
340 public virtual RdpPattern TextDeriv (string s, XmlReader reader)
342 return RdpNotAllowed.Instance;
345 internal virtual RdpPattern TextDeriv (string s, XmlReader reader, MemoizationStore memo)
347 return TextDeriv (s, reader);
350 internal virtual RdpPattern EmptyTextDeriv (MemoizationStore memo)
352 return TextDeriv (String.Empty, null, memo);
355 internal virtual RdpPattern TextOnlyDeriv ()
360 internal virtual RdpPattern TextOnlyDeriv (MemoizationStore store)
365 internal virtual RdpPattern MixedTextDeriv ()
367 return RdpNotAllowed.Instance;
370 internal virtual RdpPattern MixedTextDeriv (MemoizationStore memo)
372 return RdpNotAllowed.Instance;
375 public RdpPattern ListDeriv (string [] list, int index, XmlReader reader)
377 return listDerivInternal (list, 0, reader);
380 private RdpPattern listDerivInternal (string [] list, int start, XmlReader reader)
382 if (list.Length <= start)
384 else if (list [start].Length == 0)
385 return listDerivInternal (list, start + 1, reader);
387 return this.TextDeriv (list [start].Trim (RdpUtil.WhitespaceChars), reader).listDerivInternal (list, start + 1, reader);
391 public virtual RdpPattern Choice (RdpPattern p)
393 if (p is RdpNotAllowed)
395 else if (this is RdpNotAllowed)
398 return MakeChoice (this, p);
402 public virtual RdpPattern Group (RdpPattern p)
404 if (p is RdpNotAllowed || this is RdpNotAllowed)
405 return RdpNotAllowed.Instance;
406 else if (p is RdpEmpty)
408 else if (this is RdpEmpty)
411 return MakeGroup (this, p);
414 // Interleave(this, p)
415 public virtual RdpPattern Interleave (RdpPattern p)
417 if (p is RdpNotAllowed || this is RdpNotAllowed)
418 return RdpNotAllowed.Instance;
419 else if (p is RdpEmpty)
421 else if (this is RdpEmpty)
424 return MakeInterleave (this, p);
428 public virtual RdpPattern After (RdpPattern p)
430 if (this is RdpNotAllowed || p is RdpNotAllowed)
431 return RdpNotAllowed.Instance;
433 return MakeAfter (this, p);
437 // applyAfter((f, p1=this), p2)
438 public virtual RdpPattern ApplyAfter (RdpApplyAfterHandler h)
440 throw new Exception ("INTERNAL ERROR: should not happen. This is " + this);
443 // startTagOpenDeriv (this, qname)
444 // startTagOpenDeriv _ qn = NotAllowed (default)
445 public virtual RdpPattern StartTagOpenDeriv (string name, string ns)
447 return RdpNotAllowed.Instance;
450 internal virtual RdpPattern StartTagOpenDeriv (string name, string ns, MemoizationStore memo)
452 return StartTagOpenDeriv (name, ns);
455 // attDeriv(ctx, this, att)
456 // attDeriv _ _ _ = NotAllowed
457 public virtual RdpPattern AttDeriv (string name, string ns, string value, XmlReader reader)
459 return RdpNotAllowed.Instance;
462 public virtual RdpPattern StartAttDeriv (string name, string ns)
464 return RdpNotAllowed.Instance;
467 internal virtual RdpPattern StartAttDeriv (string name, string ns, MemoizationStore memo)
469 return StartAttDeriv (name, ns);
472 public virtual RdpPattern EndAttDeriv ()
474 return RdpNotAllowed.Instance;
477 internal virtual RdpPattern EndAttDeriv (MemoizationStore memo)
479 return EndAttDeriv ();
482 public bool ValueMatch (string s, XmlReader reader)
484 return Nullable && Util.IsWhitespace (s) ||
485 TextDeriv (s, reader).Nullable;
488 public virtual RdpPattern StartTagCloseDeriv ()
493 internal virtual RdpPattern StartTagCloseDeriv (MemoizationStore memo)
495 return StartTagCloseDeriv ();
498 public RdpPattern OneOrMore ()
500 if (PatternType == RelaxngPatternType.NotAllowed)
501 return RdpNotAllowed.Instance;
503 return MakeOneOrMore (this);
506 public virtual RdpPattern EndTagDeriv ()
508 return RdpNotAllowed.Instance;
511 internal virtual RdpPattern EndTagDeriv (MemoizationStore memo)
513 return EndTagDeriv ();
519 public class RdpEmpty : RdpPattern
521 public RdpEmpty () {}
524 instance = new RdpEmpty ();
527 public override bool Nullable {
531 internal override bool IsTextValueDependent {
532 get { return false; }
535 internal override bool IsContextDependent {
536 get { return false; }
539 static RdpEmpty instance;
540 public static RdpEmpty Instance {
541 get { return instance; }
544 public override RelaxngPatternType PatternType {
545 get { return RelaxngPatternType.Empty; }
548 public override RdpContentType ContentType {
549 get { return RdpContentType.Empty; }
552 public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)
557 internal override void MarkReachableDefs ()
562 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
565 throw new RelaxngException ("empty cannot appear under except of a data pattern.");
568 internal override bool ContainsText()
575 public class RdpNotAllowed : RdpPattern
577 public RdpNotAllowed () {}
578 static RdpNotAllowed ()
580 instance = new RdpNotAllowed ();
583 static RdpNotAllowed instance;
584 public static RdpNotAllowed Instance {
585 get { return instance; }
588 public override bool Nullable {
589 get { return false; }
592 internal override bool IsTextValueDependent {
593 get { return false; }
596 internal override bool IsContextDependent {
597 get { return false; }
600 public override RdpPattern ApplyAfter (RdpApplyAfterHandler h)
602 return RdpNotAllowed.Instance;
605 public override RelaxngPatternType PatternType {
606 get { return RelaxngPatternType.NotAllowed; }
609 public override RdpContentType ContentType {
610 get { return RdpContentType.Empty; }
613 internal override void MarkReachableDefs ()
618 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
623 internal override bool ContainsText()
628 public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)
630 // FIXME: Supposed to clear something here?
635 public class RdpText : RdpPattern
637 static RdpText instance;
638 public static RdpText Instance {
639 get { return instance; }
645 instance = new RdpText ();
648 public override bool Nullable {
652 internal override bool IsTextValueDependent {
653 get { return false; }
656 internal override bool IsContextDependent {
657 get { return false; }
660 public override RelaxngPatternType PatternType {
661 get { return RelaxngPatternType.Text; }
664 public override RdpContentType ContentType {
665 get { return RdpContentType.Complex; }
668 public override RdpPattern TextDeriv (string s, XmlReader reader)
673 internal override RdpPattern EmptyTextDeriv (MemoizationStore memo)
678 internal override RdpPattern MixedTextDeriv ()
683 internal override RdpPattern MixedTextDeriv (MemoizationStore memo)
688 internal override void MarkReachableDefs ()
693 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
696 throw new RelaxngException ("text is not allowed under a list.");
698 throw new RelaxngException ("text is not allowed under except of a list.");
701 internal override bool ContainsText()
706 public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)
713 public abstract class RdpAbstractBinary : RdpPattern
715 public RdpAbstractBinary (RdpPattern l, RdpPattern r)
722 public RdpPattern LValue {
728 public RdpPattern RValue {
733 RdpContentType computedContentType = RdpContentType.Invalid;
734 public override RdpContentType ContentType {
736 if (computedContentType == RdpContentType.Invalid) {
737 if (l.ContentType == RdpContentType.Empty)
738 computedContentType = r.ContentType;
739 else if (r.ContentType == RdpContentType.Empty)
740 computedContentType = l.ContentType;
741 else if ((l.ContentType & RdpContentType.Simple) != 0 || ((r.ContentType & RdpContentType.Simple) != 0))
742 throw new RelaxngException ("The content type of this group is invalid.");
744 computedContentType = RdpContentType.Complex;
746 return computedContentType;
751 internal override RdpPattern ExpandRef (Hashtable defs)
754 l = l.ExpandRef (defs);
755 r = r.ExpandRef (defs);
760 internal override RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited)
762 if (visited.Contains (this))
764 visited.Add (this, this);
766 if (LValue.PatternType == RelaxngPatternType.NotAllowed ||
767 RValue.PatternType == RelaxngPatternType.NotAllowed) {
769 return RdpNotAllowed.Instance;
770 } else if (LValue.PatternType == RelaxngPatternType.Empty) {
772 return RValue.ReduceEmptyAndNotAllowed (ref result, visited);
773 } else if (RValue.PatternType == RelaxngPatternType.Empty) {
775 return LValue.ReduceEmptyAndNotAllowed (ref result, visited);
777 LValue = LValue.ReduceEmptyAndNotAllowed (ref result, visited);
778 RValue = RValue.ReduceEmptyAndNotAllowed (ref result, visited);
783 internal override void MarkReachableDefs ()
785 l.MarkReachableDefs ();
786 r.MarkReachableDefs ();
789 internal override bool ContainsText()
791 return l.ContainsText () || r.ContainsText ();
794 // 7.3 (group/interleave attribute names) and
795 // part of 7.4 (interleave element names)
796 // FIXME: Actually it should be done against the correct
797 // simplified grammar, expanding all refs.
798 internal void CheckNameOverlap (bool checkElements)
800 if (RdpUtil.NamesOverlap (LValue, RValue, checkElements))
801 throw new RelaxngException ("Duplicate attributes inside a group or an interleave is not allowed.");
807 public class RdpChoice : RdpAbstractBinary
809 public RdpChoice (RdpPattern l, RdpPattern r) : base (l, r)
813 public override bool Nullable {
815 if (!nullableComputed) {
817 LValue.Nullable || RValue.Nullable;
818 nullableComputed = true;
824 bool isTextValueDependentComputed;
825 bool isTextValueDependent;
827 internal override bool IsTextValueDependent {
829 if (!isTextValueDependentComputed) {
830 isTextValueDependent = LValue.IsTextValueDependent || RValue.IsTextValueDependent;
831 isTextValueDependentComputed = true;
833 return isTextValueDependent;
837 bool isContextDependentComputed;
838 bool isContextDependent;
840 internal override bool IsContextDependent {
842 if (!isContextDependentComputed) {
843 isContextDependent = LValue.IsContextDependent || RValue.IsContextDependent;
844 isContextDependentComputed = true;
846 return isContextDependent;
850 public override RelaxngPatternType PatternType {
851 get { return RelaxngPatternType.Choice; }
854 RdpContentType computedContentType = RdpContentType.Invalid;
855 public override RdpContentType ContentType {
857 if (computedContentType == RdpContentType.Invalid) {
858 if (LValue.ContentType == RdpContentType.Simple ||
859 RValue.ContentType == RdpContentType.Simple)
860 computedContentType = RdpContentType.Simple;
862 computedContentType = base.ContentType;
864 return computedContentType;
868 public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)
870 LValue.GetLabels (elements, attributes, collectNameClass);
871 RValue.GetLabels (elements, attributes, collectNameClass);
875 internal override RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited)
877 if (visited.Contains (this))
879 visited.Add (this, this);
881 if (LValue.PatternType == RelaxngPatternType.NotAllowed &&
882 RValue.PatternType == RelaxngPatternType.NotAllowed) {
884 return RdpNotAllowed.Instance;
885 } else if (LValue.PatternType == RelaxngPatternType.NotAllowed) {
887 return RValue.ReduceEmptyAndNotAllowed (ref result, visited);
888 } else if (RValue.PatternType == RelaxngPatternType.NotAllowed) {
890 return LValue.ReduceEmptyAndNotAllowed (ref result, visited);
891 } else if (LValue.PatternType == RelaxngPatternType.Empty &&
892 RValue.PatternType == RelaxngPatternType.Empty) {
894 return RdpEmpty.Instance;
895 } else if (RValue.PatternType == RelaxngPatternType.Empty) {
897 RValue = LValue.ReduceEmptyAndNotAllowed (ref result, visited);
898 LValue = RdpEmpty.Instance;
901 LValue = LValue.ReduceEmptyAndNotAllowed (ref result, visited);
902 RValue = RValue.ReduceEmptyAndNotAllowed (ref result, visited);
907 public override RdpPattern TextDeriv (string s, XmlReader reader)
909 return LValue.TextDeriv (s, reader).Choice (RValue.TextDeriv (s, reader));
912 internal override RdpPattern TextDeriv (string s, XmlReader reader, MemoizationStore memo)
914 return memo.TextDeriv (LValue, s, reader).Choice (memo.TextDeriv (RValue, s, reader));
917 internal override RdpPattern EmptyTextDeriv (MemoizationStore memo)
919 return memo.EmptyTextDeriv (LValue)
920 .Choice (memo.EmptyTextDeriv (RValue));
923 internal override RdpPattern TextOnlyDeriv ()
925 return LValue.TextOnlyDeriv ().Choice (
926 RValue.TextOnlyDeriv ());
929 internal override RdpPattern TextOnlyDeriv (MemoizationStore memo)
931 return memo.TextOnlyDeriv (LValue).Choice (
932 memo.TextOnlyDeriv (RValue));
935 internal override RdpPattern MixedTextDeriv ()
937 return LValue.MixedTextDeriv ().Choice (
938 RValue.MixedTextDeriv ());
941 internal override RdpPattern MixedTextDeriv (MemoizationStore memo)
943 return memo.MixedTextDeriv (LValue).Choice (
944 memo.MixedTextDeriv (RValue));
947 public override RdpPattern ApplyAfter (RdpApplyAfterHandler handler)
949 // return handler (LValue).Choice (handler (RValue));
950 return LValue.ApplyAfter (handler).Choice (RValue.ApplyAfter (handler));
953 public override RdpPattern StartTagOpenDeriv (string name, string ns)
956 return RdpUtil.Choice (
957 RdpUtil.StartTagOpenDeriv (LValue, qname),
958 RdpUtil.StartTagOpenDeriv (RValue, qname));
960 RdpPattern lDeriv = LValue.StartTagOpenDeriv (name, ns);
961 return lDeriv.Choice (RValue.StartTagOpenDeriv (name, ns));
965 internal override RdpPattern StartTagOpenDeriv (string name, string ns, MemoizationStore memo)
967 RdpPattern lDeriv = memo.StartTagOpenDeriv (LValue, name, ns);
968 return lDeriv.Choice (memo.StartTagOpenDeriv (RValue, name, ns));
971 // attDeriv cx (Choice p1 p2) att =
972 // choice (attDeriv cx p1 att) (attDeriv cx p2 att)
973 public override RdpPattern AttDeriv (string name, string ns, string value, XmlReader reader)
975 return LValue.AttDeriv (name, ns, value, reader)
976 .Choice (RValue.AttDeriv (name, ns, value, reader));
979 public override RdpPattern StartAttDeriv (string name, string ns)
981 RdpPattern lDeriv = LValue.StartAttDeriv (name, ns);
982 return lDeriv.Choice (RValue.StartAttDeriv (name, ns));
985 internal override RdpPattern StartAttDeriv (string name, string ns, MemoizationStore memo)
987 return memo.StartAttDeriv (LValue, name, ns)
988 .Choice (memo.StartAttDeriv (RValue, name, ns));
991 public override RdpPattern EndAttDeriv ()
993 return LValue.EndAttDeriv ().Choice (RValue.EndAttDeriv ());
996 internal override RdpPattern EndAttDeriv (MemoizationStore memo)
998 return memo.EndAttDeriv (LValue).Choice (memo.EndAttDeriv (RValue));
1001 // startTagCloseDeriv (Choice p1 p2) =
1002 // choice (startTagCloseDeriv p1) (startTagCloseDeriv p2)
1003 public override RdpPattern StartTagCloseDeriv ()
1005 return LValue.StartTagCloseDeriv ()
1006 .Choice (RValue.StartTagCloseDeriv ());
1009 internal override RdpPattern StartTagCloseDeriv (MemoizationStore memo)
1011 return memo.StartTagCloseDeriv (LValue)
1012 .Choice (memo.StartTagCloseDeriv (RValue));
1015 public override RdpPattern EndTagDeriv ()
1017 return LValue.EndTagDeriv ().Choice (RValue.EndTagDeriv ());
1020 internal override RdpPattern EndTagDeriv (MemoizationStore memo)
1022 return memo.EndTagDeriv (LValue).Choice (memo.EndTagDeriv (RValue));
1025 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
1027 LValue.CheckConstraints (attribute, oneOrMore, oneOrMoreGroup, oneOrMoreInterleave, list, dataExcept);
1028 RValue.CheckConstraints (attribute, oneOrMore, oneOrMoreGroup, oneOrMoreInterleave, list, dataExcept);
1033 public class RdpInterleave : RdpAbstractBinary
1035 public RdpInterleave (RdpPattern l, RdpPattern r) : base (l, r)
1039 public override bool Nullable {
1041 if (!nullableComputed) {
1043 LValue.Nullable && RValue.Nullable;
1044 nullableComputed = true;
1050 internal override bool IsTextValueDependent {
1051 get { return LValue.IsTextValueDependent || RValue.IsTextValueDependent; }
1054 internal override bool IsContextDependent {
1055 get { return LValue.IsContextDependent || RValue.IsContextDependent; }
1058 public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)
1060 LValue.GetLabels (elements, attributes, collectNameClass);
1061 RValue.GetLabels (elements, attributes, collectNameClass);
1064 internal override RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited)
1066 if (visited.Contains (this))
1068 visited.Add (this, this);
1070 if (LValue.PatternType == RelaxngPatternType.NotAllowed ||
1071 RValue.PatternType == RelaxngPatternType.NotAllowed) {
1073 return RdpNotAllowed.Instance;
1075 LValue = LValue.ReduceEmptyAndNotAllowed (ref result, visited);
1076 RValue = RValue.ReduceEmptyAndNotAllowed (ref result, visited);
1081 public override RdpPattern TextDeriv (string s, XmlReader reader)
1083 return LValue.TextDeriv (s, reader).Interleave (RValue)
1084 .Choice (LValue.Interleave (RValue.TextDeriv (s, reader)));
1087 internal override RdpPattern TextDeriv (string s, XmlReader reader, MemoizationStore memo)
1089 return memo.TextDeriv (LValue, s, reader).Interleave (RValue)
1090 .Choice (LValue.Interleave (memo.TextDeriv (RValue, s, reader)));
1093 internal override RdpPattern EmptyTextDeriv (MemoizationStore memo)
1095 return memo.EmptyTextDeriv (LValue).Interleave (RValue)
1096 .Choice (LValue.Interleave (memo.EmptyTextDeriv (RValue)));
1099 internal override RdpPattern TextOnlyDeriv ()
1101 return LValue.TextOnlyDeriv ().Interleave (
1102 RValue.TextOnlyDeriv ());
1105 internal override RdpPattern TextOnlyDeriv (MemoizationStore memo)
1107 return memo.TextOnlyDeriv (LValue).Interleave (
1108 memo.TextOnlyDeriv (RValue));
1111 internal override RdpPattern MixedTextDeriv ()
1113 return LValue.MixedTextDeriv ().Interleave (RValue).Choice (
1114 LValue.Interleave (RValue.MixedTextDeriv ()));
1117 internal override RdpPattern MixedTextDeriv (MemoizationStore memo)
1119 return memo.MixedTextDeriv (LValue).Interleave (RValue).Choice (
1120 LValue.Interleave (memo.MixedTextDeriv (RValue)));
1123 // => choice (applyAfter (flip interleave p2) (startTagOpenDeriv p1 qn)) (applyAfter (interleave p1) (startTagOpenDeriv p2 qn)
1124 // => p1.startTagOpenDeriv(qn).applyAfter (flip interleave p2).choice (p2.startTagOpenDeriv(qn).applyAfter (interleave p1) )
1125 public override RdpPattern StartTagOpenDeriv (string name, string ns)
1127 RdpPattern handledL = LValue.StartTagOpenDeriv (name, ns);
1128 RdpPattern handledR = RValue.StartTagOpenDeriv (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 internal override RdpPattern StartTagOpenDeriv (string name, string ns, MemoizationStore memo)
1137 RdpPattern handledL = memo.StartTagOpenDeriv (LValue, name, ns);
1138 RdpPattern handledR = memo.StartTagOpenDeriv (RValue, name, ns);
1139 RdpFlip flipL = MakeFlip (RdpUtil.InterleaveFunction, RValue);
1140 RdpPattern choiceL = handledL.ApplyAfter (new RdpApplyAfterHandler (flipL.Apply));
1141 RdpPattern choiceR = handledR.ApplyAfter (new RdpApplyAfterHandler (LValue.Interleave));
1142 return choiceL.Choice (choiceR);
1145 // attDeriv cx (Interleave p1 p2) att =
1146 // choice (interleave (attDeriv cx p1 att) p2)
1147 // (interleave p1 (attDeriv cx p2 att))
1148 public override RdpPattern AttDeriv (string name, string ns, string value, XmlReader reader)
1150 return LValue.AttDeriv (name, ns, value, reader)
1151 .Interleave (RValue)
1152 .Choice (LValue.Interleave (
1153 RValue.AttDeriv (name, ns, value, reader)));
1156 public override RdpPattern StartAttDeriv (string name, string ns)
1158 RdpPattern handledL = LValue.StartAttDeriv (name, ns);
1159 RdpPattern handledR = RValue.StartAttDeriv (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 internal override RdpPattern StartAttDeriv (string name, string ns, MemoizationStore memo)
1168 RdpPattern handledL = memo.StartAttDeriv (LValue, name, ns);
1169 RdpPattern handledR = memo.StartAttDeriv (RValue, name, ns);
1170 RdpFlip flipL = MakeFlip (RdpUtil.InterleaveFunction, RValue);
1171 RdpPattern choiceL = handledL.ApplyAfter (new RdpApplyAfterHandler (flipL.Apply));
1172 RdpPattern choiceR = handledR.ApplyAfter (new RdpApplyAfterHandler (LValue.Interleave));
1173 return choiceL.Choice (choiceR);
1176 // startTagCloseDeriv (Interleave p1 p2) =
1177 // interleave (startTagCloseDeriv p1) (startTagCloseDeriv p2)
1178 public override RdpPattern StartTagCloseDeriv ()
1180 return LValue.StartTagCloseDeriv ()
1181 .Interleave (RValue.StartTagCloseDeriv ());
1184 internal override RdpPattern StartTagCloseDeriv (MemoizationStore memo)
1186 return memo.StartTagCloseDeriv (LValue)
1187 .Interleave (memo.StartTagCloseDeriv (RValue));
1190 public override RelaxngPatternType PatternType {
1191 get { return RelaxngPatternType.Interleave; }
1194 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
1197 throw new RelaxngException ("interleave is not allowed under a list.");
1199 throw new RelaxngException ("interleave is not allowed under except of a data.");
1202 LValue.CheckConstraints (attribute, oneOrMore, oneOrMoreGroup, oneOrMore, list, dataExcept);
1203 RValue.CheckConstraints (attribute, oneOrMore, oneOrMoreGroup, oneOrMore, list, dataExcept);
1205 // unique name analysis - 7.3 and part of 7.4
1206 CheckNameOverlap (true);
1208 // (2) text/text prohibited
1209 if (LValue.ContainsText () && RValue.ContainsText ())
1210 throw new RelaxngException ("Both branches of the interleave contains a text pattern.");
1215 public class RdpGroup : RdpAbstractBinary
1217 public RdpGroup (RdpPattern l, RdpPattern r) : base (l, r)
1221 public override bool Nullable {
1223 if (!nullableComputed) {
1225 LValue.Nullable && RValue.Nullable;
1226 nullableComputed = true;
1232 internal override bool IsTextValueDependent {
1233 get { return LValue.IsTextValueDependent || (LValue.Nullable ? RValue.IsTextValueDependent : false); }
1236 internal override bool IsContextDependent {
1237 get { return LValue.IsContextDependent || (LValue.Nullable ? RValue.IsContextDependent : false); }
1240 public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)
1242 LValue.GetLabels (elements, attributes, collectNameClass);
1243 if (LValue.Nullable)
1244 RValue.GetLabels (elements, attributes, collectNameClass);
1246 RValue.GetLabels (null, attributes, collectNameClass);
1249 public override RdpPattern TextDeriv (string s, XmlReader reader)
1251 RdpPattern p = LValue.TextDeriv (s, reader);
1252 p = (p.PatternType == RelaxngPatternType.NotAllowed) ?
1253 p : p.Group (RValue);
1254 return LValue.Nullable ?
1255 p.Choice (RValue.TextDeriv (s, reader)) : p;
1258 internal override RdpPattern TextDeriv (string s, XmlReader reader, MemoizationStore memo)
1260 RdpPattern p = memo.TextDeriv (LValue, s, reader);
1261 p = (p.PatternType == RelaxngPatternType.NotAllowed) ?
1262 p : p.Group (RValue);
1263 return LValue.Nullable ?
1264 p.Choice (memo.TextDeriv (RValue, s, reader)) : p;
1267 internal override RdpPattern EmptyTextDeriv (MemoizationStore memo)
1269 RdpPattern p = memo.EmptyTextDeriv (LValue);
1270 p = p.PatternType == RelaxngPatternType.NotAllowed ?
1271 p : p.Group (RValue);
1272 return LValue.Nullable ?
1273 p.Choice (memo.EmptyTextDeriv (RValue)) : p;
1276 internal override RdpPattern TextOnlyDeriv ()
1278 RdpPattern p = LValue.TextOnlyDeriv ();
1279 return p.PatternType == RelaxngPatternType.NotAllowed ?
1280 p : p.Group (RValue.TextOnlyDeriv ());
1283 internal override RdpPattern TextOnlyDeriv (MemoizationStore memo)
1285 RdpPattern p = memo.TextOnlyDeriv (LValue);
1286 return p.PatternType == RelaxngPatternType.NotAllowed ?
1287 p : p.Group (memo.TextOnlyDeriv (RValue));
1290 internal override RdpPattern MixedTextDeriv ()
1292 RdpPattern p = LValue.MixedTextDeriv ().Group (RValue);
1293 return LValue.Nullable ?
1294 p.Choice (RValue.MixedTextDeriv ()) : p;
1297 internal override RdpPattern MixedTextDeriv (MemoizationStore memo)
1299 RdpPattern p = memo.MixedTextDeriv (LValue).Group (RValue);
1300 return LValue.Nullable ?
1301 p.Choice (memo.MixedTextDeriv (RValue)) : p;
1304 // startTagOpenDeriv (Group p1 p2) qn =
1305 // let x = applyAfter (flip group p2) (startTagOpenDeriv p1 qn)
1306 // in if nullable p1 then
1307 // choice x (startTagOpenDeriv p2 qn)
1310 public override RdpPattern StartTagOpenDeriv (string name, string ns)
1312 RdpPattern handled = LValue.StartTagOpenDeriv (name, ns);
1313 RdpFlip f = MakeFlip (RdpUtil.GroupFunction, RValue);
1314 RdpPattern x = handled.ApplyAfter (new RdpApplyAfterHandler (f.Apply));
1315 if (LValue.Nullable)
1316 return x.Choice (RValue.StartTagOpenDeriv (name, ns));
1321 internal override RdpPattern StartTagOpenDeriv (string name, string ns, MemoizationStore memo)
1323 RdpPattern handled = memo.StartTagOpenDeriv (LValue, name, ns);
1324 RdpFlip f = MakeFlip (RdpUtil.GroupFunction, RValue);
1325 RdpPattern x = handled.ApplyAfter (new RdpApplyAfterHandler (f.Apply));
1326 if (LValue.Nullable)
1327 return x.Choice (memo.StartTagOpenDeriv (RValue, name, ns));
1332 // attDeriv cx (Group p1 p2) att =
1333 // choice (group (attDeriv cx p1 att) p2)
1334 // (group p1 (attDeriv cx p2 att))
1335 public override RdpPattern AttDeriv (string name, string ns, string value, XmlReader reader)
1337 return LValue.AttDeriv (name, ns, value, reader).Group (RValue)
1338 .Choice (LValue.Group (
1339 RValue.AttDeriv (name, ns, value, reader)));
1342 // startAttDeriv (group p1 p2) == startAttDeriv (interleave p1 p2)
1343 public override RdpPattern StartAttDeriv (string name, string ns)
1345 RdpPattern handledL = LValue.StartAttDeriv (name, ns);
1346 RdpPattern handledR = RValue.StartAttDeriv (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 internal override RdpPattern StartAttDeriv (string name, string ns, MemoizationStore memo)
1355 RdpPattern handledL = memo.StartAttDeriv (LValue, name, ns);
1356 RdpPattern handledR = memo.StartAttDeriv (RValue, name, ns);
1357 RdpFlip flipL = MakeFlip (RdpUtil.GroupFunction, RValue);
1358 RdpPattern choiceL = handledL.ApplyAfter (new RdpApplyAfterHandler (flipL.Apply));
1359 RdpPattern choiceR = handledR.ApplyAfter (new RdpApplyAfterHandler (LValue.Group));
1360 return choiceL.Choice (choiceR);
1363 // startTagCloseDeriv (Group p1 p2) =
1364 // group (startTagCloseDeriv p1) (startTagCloseDeriv p2)
1365 public override RdpPattern StartTagCloseDeriv ()
1367 RdpPattern p = LValue.StartTagCloseDeriv ();
1368 return p.PatternType == RelaxngPatternType.NotAllowed ?
1369 p : p.Group (RValue.StartTagCloseDeriv ());
1372 internal override RdpPattern StartTagCloseDeriv (MemoizationStore memo)
1374 RdpPattern p = memo.StartTagCloseDeriv (LValue);
1375 return p.PatternType == RelaxngPatternType.NotAllowed ?
1376 p : p.Group (memo.StartTagCloseDeriv (RValue));
1379 public override RelaxngPatternType PatternType {
1380 get { return RelaxngPatternType.Group; }
1383 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
1386 throw new RelaxngException ("interleave is not allowed under except of a data.");
1388 LValue.CheckConstraints (attribute, oneOrMore, oneOrMore, oneOrMoreInterleave, list, dataExcept);
1389 RValue.CheckConstraints (attribute, oneOrMore, oneOrMore, oneOrMoreInterleave, list, dataExcept);
1392 CheckNameOverlap (false);
1396 public abstract class RdpAbstractSingleContent : RdpPattern
1401 internal override RdpPattern ExpandRef (Hashtable defs)
1404 child = child.ExpandRef (defs);
1408 public RdpAbstractSingleContent (RdpPattern p)
1413 public RdpPattern Child {
1414 get { return child; }
1415 set { child = value; }
1418 internal override void MarkReachableDefs ()
1420 child.MarkReachableDefs ();
1423 internal override bool ContainsText()
1425 return child.ContainsText ();
1430 public class RdpOneOrMore : RdpAbstractSingleContent
1432 public RdpOneOrMore (RdpPattern p) : base (p)
1436 public override RelaxngPatternType PatternType {
1437 get { return RelaxngPatternType.OneOrMore; }
1440 public override RdpContentType ContentType {
1442 if (Child.ContentType == RdpContentType.Simple)
1443 throw new RelaxngException ("Invalid content type was found.");
1444 return Child.ContentType;
1448 public override bool Nullable {
1449 get { return Child.Nullable; }
1452 internal override bool IsTextValueDependent {
1453 get { return Child.IsTextValueDependent; }
1456 internal override bool IsContextDependent {
1457 get { return Child.IsContextDependent; }
1460 public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)
1462 Child.GetLabels (elements, attributes, collectNameClass);
1465 internal override RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited)
1467 if (visited.Contains (this))
1469 visited.Add (this, this);
1471 if (Child.PatternType == RelaxngPatternType.NotAllowed) {
1473 return RdpNotAllowed.Instance;
1474 } else if (Child.PatternType == RelaxngPatternType.Empty)
1475 return RdpEmpty.Instance;
1477 Child = Child.ReduceEmptyAndNotAllowed (ref result, visited);
1482 public override RdpPattern TextDeriv (string s, XmlReader reader)
1484 RdpPattern p = Child.TextDeriv (s, reader);
1485 return p.PatternType == RelaxngPatternType.NotAllowed ?
1486 p : p.Group (this.Choice (RdpEmpty.Instance));
1489 internal override RdpPattern TextDeriv (string s, XmlReader reader, MemoizationStore memo)
1491 RdpPattern p = memo.TextDeriv (Child, s, reader);
1492 return p.PatternType == RelaxngPatternType.NotAllowed ?
1493 p : p.Group (this.Choice (RdpEmpty.Instance));
1496 internal override RdpPattern EmptyTextDeriv (MemoizationStore memo)
1498 RdpPattern p = memo.EmptyTextDeriv (Child);
1499 return p.PatternType == RelaxngPatternType.NotAllowed ?
1500 p : p.Group (this.Choice (RdpEmpty.Instance));
1503 internal override RdpPattern TextOnlyDeriv ()
1505 return Child.TextOnlyDeriv ().OneOrMore ();
1508 internal override RdpPattern TextOnlyDeriv (MemoizationStore memo)
1510 return memo.TextOnlyDeriv (Child).OneOrMore ();
1513 internal override RdpPattern MixedTextDeriv ()
1515 RdpPattern p = Child.MixedTextDeriv ();
1516 return p.PatternType == RelaxngPatternType.NotAllowed ?
1517 p : p.Group (this.Choice (RdpEmpty.Instance));
1520 internal override RdpPattern MixedTextDeriv (MemoizationStore memo)
1522 RdpPattern p = memo.MixedTextDeriv (Child);
1523 return p.PatternType == RelaxngPatternType.NotAllowed ?
1524 p : p.Group (this.Choice (RdpEmpty.Instance));
1527 // attDeriv cx (OneOrMore p) att =
1528 // group (attDeriv cx p att) (choice (OneOrMore p) Empty)
1529 public override RdpPattern AttDeriv (string name, string ns, string value, XmlReader reader)
1531 RdpPattern p = Child.AttDeriv (name, ns, value, reader);
1532 return p.PatternType == RelaxngPatternType.NotAllowed ?
1533 p : p.Group (Choice (RdpEmpty.Instance));
1536 // startTagOpenDeriv (OneOrMore p) qn =
1537 // applyAfter (flip group (choice (OneOrMore p) Empty))
1538 // (startTagOpenDeriv p qn)
1539 public override RdpPattern StartTagOpenDeriv (string name, string ns)
1541 RdpPattern rest = RdpEmpty.Instance.Choice (Child.OneOrMore ());
1542 RdpPattern handled = Child.StartTagOpenDeriv (name, ns);
1543 RdpFlip f = MakeFlip (RdpUtil.GroupFunction, rest);
1544 return handled.ApplyAfter (new RdpApplyAfterHandler (f.Apply));
1547 internal override RdpPattern StartTagOpenDeriv (string name, string ns, MemoizationStore memo)
1549 RdpPattern rest = RdpEmpty.Instance.Choice (Child.OneOrMore ());
1550 RdpPattern handled = memo.StartTagOpenDeriv (Child, name, ns);
1551 RdpFlip f = MakeFlip (RdpUtil.GroupFunction, rest);
1552 return handled.ApplyAfter (new RdpApplyAfterHandler (f.Apply));
1555 public override RdpPattern StartAttDeriv (string name, string ns)
1557 RdpPattern rest = RdpEmpty.Instance.Choice (Child.OneOrMore ());
1558 RdpPattern handled = Child.StartAttDeriv (name, ns);
1559 RdpFlip f = MakeFlip (RdpUtil.GroupFunction, rest);
1560 return handled.ApplyAfter (new RdpApplyAfterHandler (f.Apply));
1563 internal override RdpPattern StartAttDeriv (string name, string ns, MemoizationStore memo)
1565 RdpPattern rest = RdpEmpty.Instance.Choice (Child.OneOrMore ());
1566 RdpPattern handled = memo.StartAttDeriv (Child, name, ns);
1567 RdpFlip f = MakeFlip (RdpUtil.GroupFunction, rest);
1568 return handled.ApplyAfter (new RdpApplyAfterHandler (f.Apply));
1571 // startTagCloseDeriv (OneOrMore p) =
1572 // oneOrMore (startTagCloseDeriv p)
1573 public override RdpPattern StartTagCloseDeriv ()
1576 return RdpUtil.OneOrMore (
1577 RdpUtil.StartTagCloseDeriv (children));
1579 return Child.StartTagCloseDeriv ().OneOrMore ();
1583 internal override RdpPattern StartTagCloseDeriv (MemoizationStore memo)
1585 return memo.StartTagCloseDeriv (Child).OneOrMore ();
1588 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
1591 throw new RelaxngException ("oneOrMore is not allowed under except of a data.");
1592 this.Child.CheckConstraints (attribute, true, oneOrMoreGroup, oneOrMoreInterleave, list, dataExcept);
1597 public class RdpList : RdpAbstractSingleContent
1599 public RdpList (RdpPattern p) : base (p)
1603 internal override RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited)
1605 if (visited.Contains (this))
1607 visited.Add (this, this);
1609 if (Child.PatternType == RelaxngPatternType.NotAllowed) {
1611 return RdpNotAllowed.Instance;
1613 Child = Child.ReduceEmptyAndNotAllowed (ref result, visited);
1618 public override bool Nullable {
1619 get { return false; }
1622 internal override bool IsTextValueDependent {
1623 get { return true; }
1626 internal override bool IsContextDependent {
1627 get { return Child.IsContextDependent; }
1630 public override RelaxngPatternType PatternType {
1631 get { return RelaxngPatternType.List; }
1634 public override RdpContentType ContentType {
1635 get { return RdpContentType.Simple; }
1638 public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)
1640 Child.GetLabels (elements, attributes, collectNameClass);
1643 public override RdpPattern TextDeriv (string s, XmlReader reader)
1645 s = Util.NormalizeWhitespace (s);
1647 RdpPattern p = Child.ListDeriv (s.Split (RdpUtil.WhitespaceChars), 0, reader);
1649 return RdpEmpty.Instance;
1651 return RdpNotAllowed.Instance;
1654 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
1657 throw new RelaxngException ("list is not allowed uner another list.");
1659 throw new RelaxngException ("list is not allowed under except of a data.");
1660 this.Child.CheckConstraints (attribute, oneOrMore, oneOrMoreGroup, oneOrMoreInterleave, true, dataExcept);
1665 public class RdpData : RdpPattern
1667 public RdpData (RdpDatatype dt)
1673 public RdpDatatype Datatype {
1677 public override bool Nullable {
1678 get { return false; }
1681 internal override bool IsTextValueDependent {
1682 get { return true; }
1685 internal override bool IsContextDependent {
1686 get { return dt.IsContextDependent; }
1689 public override RelaxngPatternType PatternType {
1690 get { return RelaxngPatternType.Data; }
1693 public override RdpContentType ContentType {
1694 get { return RdpContentType.Simple; }
1697 public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)
1702 public override RdpPattern TextDeriv (string s, XmlReader reader)
1704 if (dt.IsAllowed (s, reader))
1705 return RdpEmpty.Instance;
1707 return RdpNotAllowed.Instance;
1710 internal override void MarkReachableDefs ()
1715 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
1720 internal override bool ContainsText()
1727 public class RdpDataExcept : RdpData
1729 public RdpDataExcept (RdpDatatype dt, RdpPattern except)
1732 this.except = except;
1736 public RdpPattern Except {
1737 get { return except; }
1738 set { except = value; }
1741 public override RelaxngPatternType PatternType {
1742 get { return RelaxngPatternType.DataExcept; }
1745 public override RdpContentType ContentType {
1747 RdpContentType c = except.ContentType; // conformance required for except pattern.
1748 return RdpContentType.Simple;
1752 internal override RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited)
1754 if (visited.Contains (this))
1756 visited.Add (this, this);
1758 if (except.PatternType == RelaxngPatternType.NotAllowed) {
1760 return new RdpData (this.Datatype);
1762 except = except.ReduceEmptyAndNotAllowed (ref result, visited);
1767 public override RdpPattern TextDeriv (string s, XmlReader reader)
1769 if (Datatype.IsAllowed (s, reader) && !except.TextDeriv (s, reader).Nullable)
1770 return RdpEmpty.Instance;
1772 return RdpNotAllowed.Instance;
1775 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
1777 this.except.CheckConstraints (attribute, oneOrMore, oneOrMoreGroup, oneOrMoreInterleave, list, true);
1780 internal override bool ContainsText()
1782 return except.ContainsText ();
1787 public class RdpValue : RdpPattern
1789 public RdpValue (RdpDatatype dt, string value)
1796 public RdpDatatype Datatype {
1801 public string Value {
1802 get { return value; }
1805 public override bool Nullable {
1806 get { return false; }
1809 internal override bool IsTextValueDependent {
1810 get { return true; }
1813 internal override bool IsContextDependent {
1814 get { return dt.IsContextDependent; }
1817 public override RelaxngPatternType PatternType {
1818 get { return RelaxngPatternType.Value; }
1821 public override RdpContentType ContentType {
1822 get { return RdpContentType.Simple; }
1825 public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)
1831 RdpPattern cachedPattern;
1833 public override RdpPattern TextDeriv (string s, XmlReader reader)
1835 if (s == cachedValue && !IsContextDependent)
1836 return cachedPattern;
1837 cachedPattern = TextDerivCore (s, reader);
1839 return cachedPattern;
1842 RdpPattern TextDerivCore (string s, XmlReader reader)
1844 if (dt.IsTypeEqual (value, s, reader))
1845 return RdpEmpty.Instance;
1847 return RdpNotAllowed.Instance;
1850 internal override void MarkReachableDefs ()
1855 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
1857 // nothing to be checked
1860 internal override bool ContainsText()
1867 public class RdpAttribute : RdpPattern
1869 public RdpAttribute (RdpNameClass nameClass, RdpPattern p)
1871 this.nameClass = nameClass;
1875 RdpNameClass nameClass;
1876 public RdpNameClass NameClass {
1877 get { return nameClass; }
1880 RdpPattern children;
1881 public RdpPattern Children {
1882 get { return children; }
1883 set { children = value; }
1886 public override bool Nullable {
1887 get { return false; }
1890 internal override bool IsTextValueDependent {
1891 get { return false; }
1894 internal override bool IsContextDependent {
1895 get { return false; }
1898 public override RelaxngPatternType PatternType {
1899 get { return RelaxngPatternType.Attribute; }
1902 public override RdpContentType ContentType {
1903 get { return RdpContentType.Empty; }
1906 public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)
1908 if (attributes != null) {
1909 if (collectNameClass)
1910 attributes [NameClass] = NameClass;
1912 AddNameLabel (attributes, NameClass);
1917 internal override RdpPattern ExpandRef (Hashtable defs)
1921 children = children.ExpandRef (defs);
1926 internal override RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited)
1928 if (visited.Contains (this))
1930 visited.Add (this, this);
1932 if (children.PatternType == RelaxngPatternType.NotAllowed) {
1934 return RdpNotAllowed.Instance;
1936 children = children.ReduceEmptyAndNotAllowed (ref result, visited);
1941 // attDeriv cx (Attribute nc p) (AttributeNode qn s) =
1942 // if contains nc qn && valueMatch cx p s then Empty else NotAllowed
1943 public override RdpPattern AttDeriv (string name, string ns, string value, XmlReader reader)
1945 // If value is null, then does not check ValueMatch.
1947 if (RdpUtil.Contains (this.nameClass, att.QName)
1948 && (value == null || RdpUtil.ValueMatch (ctx, this.children, att.Value)))
1949 return RdpEmpty.Instance;
1951 return RdpNotAllowed.Instance;
1953 if (nameClass.Contains (name, ns) &&
1954 (value == null || children.ValueMatch (value, reader)))
1955 return RdpEmpty.Instance;
1957 return RdpNotAllowed.Instance;
1961 public override RdpPattern StartAttDeriv (string name, string ns)
1963 return nameClass.Contains (name, ns) ?
1964 children.After (RdpEmpty.Instance) : RdpNotAllowed.Instance;
1967 internal override RdpPattern StartAttDeriv (string name, string ns, MemoizationStore memo)
1969 return nameClass.Contains (name, ns) ?
1970 children.After (RdpEmpty.Instance) : RdpNotAllowed.Instance;
1973 // startTagCloseDeriv (Attribute _ _) = NotAllowed
1974 public override RdpPattern StartTagCloseDeriv ()
1976 return RdpNotAllowed.Instance;
1979 internal override RdpPattern StartTagCloseDeriv (MemoizationStore memo)
1981 return RdpNotAllowed.Instance;
1984 internal override void MarkReachableDefs ()
1986 children.MarkReachableDefs ();
1989 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
1992 if (attribute || oneOrMoreGroup || oneOrMoreInterleave || list || dataExcept)
1993 throw new RelaxngException ("Not allowed attribute occurence was specified in the pattern.");
1995 // latter part of 7.3
1996 if (!oneOrMore && NameClass.HasInfiniteName)
1997 throw new RelaxngException ("Attributes that has an infinite name class must be repeatable.");
1999 this.Children.CheckConstraints (true, oneOrMore, false, false, false, false);
2002 internal override bool ContainsText()
2004 // This method is to detect text pattern inside interleave child.
2005 // return children.ContainsText ();
2011 public class RdpElement : RdpPattern
2013 public RdpElement (RdpNameClass nameClass, RdpPattern p)
2015 this.nameClass = nameClass;
2019 RdpNameClass nameClass;
2020 public RdpNameClass NameClass {
2021 get { return nameClass; }
2024 RdpPattern children;
2025 public RdpPattern Children {
2026 get { return children; }
2027 set { children = value; }
2030 public override bool Nullable {
2031 get { return false; }
2034 internal override bool IsTextValueDependent {
2035 get { return false; }
2038 internal override bool IsContextDependent {
2039 get { return false; }
2042 public override RelaxngPatternType PatternType {
2043 get { return RelaxngPatternType.Element; }
2046 bool contentTypeCheckDone;
2047 public override RdpContentType ContentType {
2049 if (!contentTypeCheckDone) {
2050 contentTypeCheckDone = true;
2051 RdpContentType ct = children.ContentType; // conformance required.
2053 return RdpContentType.Complex;
2057 public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)
2059 if (elements != null) {
2060 if (collectNameClass)
2061 elements [NameClass] = NameClass;
2063 AddNameLabel (elements, NameClass);
2069 short expanding; // FIXME: It is totally not required, but there is
2070 // some bugs in simplification and without it it causes infinite loop.
2071 internal override RdpPattern ExpandRef (Hashtable defs)
2075 if (expanding == 100)
2076 throw new RelaxngException (String.Format ("Invalid recursion was found. Name is {0}", nameClass));
2078 children = children.ExpandRef (defs);
2084 internal override RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited)
2086 if (visited.Contains (this))
2088 visited.Add (this, this);
2090 children = children.ReduceEmptyAndNotAllowed (ref result, visited);
2094 internal override RdpPattern TextOnlyDeriv ()
2096 return RdpNotAllowed.Instance;
2099 internal override RdpPattern TextOnlyDeriv (MemoizationStore memo)
2101 return RdpNotAllowed.Instance;
2104 public override RdpPattern StartTagOpenDeriv (string name, string ns)
2107 if (RdpUtil.Contains (this.nameClass, qname))
2108 return RdpUtil.After (this.Children, RdpEmpty.Instance);
2110 return RdpNotAllowed.Instance;
2112 return nameClass.Contains (name, ns) ?
2113 children.After (RdpEmpty.Instance) :
2114 RdpNotAllowed.Instance;
2118 internal override RdpPattern StartTagOpenDeriv (string name, string ns, MemoizationStore memo)
2120 return nameClass.Contains (name, ns) ?
2121 children.After (RdpEmpty.Instance) :
2122 RdpNotAllowed.Instance;
2125 internal override void MarkReachableDefs ()
2127 children.MarkReachableDefs ();
2130 bool constraintsChecked;
2131 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
2133 if (constraintsChecked)
2135 constraintsChecked = true;
2136 if (attribute || list || dataExcept)
2137 throw new RelaxngException ("Not allowed element occurence was specified in the pattern.");
2138 this.Children.CheckConstraints (false, false, false, oneOrMoreInterleave, false, false);
2141 internal override bool ContainsText()
2148 public class RdpAfter : RdpAbstractBinary
2150 public RdpAfter (RdpPattern l, RdpPattern r) : base (l, r)
2154 public override bool Nullable {
2155 get { return false; }
2158 internal override bool IsTextValueDependent {
2159 get { return LValue.IsTextValueDependent; }
2162 internal override bool IsContextDependent {
2163 get { return LValue.IsContextDependent; }
2166 public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass)
2168 LValue.GetLabels (elements, attributes, collectNameClass);
2171 public override RdpPattern TextDeriv (string s, XmlReader reader)
2173 return LValue.TextDeriv (s, reader).After (RValue);
2176 internal override RdpPattern TextDeriv (string s, XmlReader reader, MemoizationStore memo)
2178 return memo.TextDeriv (LValue, s, reader).After (RValue);
2181 internal override RdpPattern EmptyTextDeriv (MemoizationStore memo)
2183 return memo.EmptyTextDeriv (LValue).After (RValue);
2186 internal override RdpPattern TextOnlyDeriv ()
2188 return LValue.TextOnlyDeriv ().After (RValue);
2191 internal override RdpPattern TextOnlyDeriv (MemoizationStore memo)
2193 return memo.TextOnlyDeriv (LValue).After (RValue);
2196 internal override RdpPattern MixedTextDeriv ()
2198 return LValue.MixedTextDeriv ().After (RValue);
2201 internal override RdpPattern MixedTextDeriv (MemoizationStore memo)
2203 return memo.MixedTextDeriv (LValue).After (RValue);
2206 // startTagOpenDeriv (After p1 p2) qn =
2207 // applyAfter (flip after p2) (startTagOpenDeriv p1 qn)
2208 public override RdpPattern StartTagOpenDeriv (string name, string ns)
2210 RdpPattern handled = LValue.StartTagOpenDeriv (name, ns);
2211 RdpFlip f = MakeFlip (RdpUtil.AfterFunction, RValue);
2212 return handled.ApplyAfter (new RdpApplyAfterHandler (
2216 internal override RdpPattern StartTagOpenDeriv (string name, string ns, MemoizationStore memo)
2218 RdpPattern handled = memo.StartTagOpenDeriv (LValue, name, ns);
2219 RdpFlip f = MakeFlip (RdpUtil.AfterFunction, RValue);
2220 return handled.ApplyAfter (new RdpApplyAfterHandler (
2224 public override RdpPattern ApplyAfter (RdpApplyAfterHandler handler)
2226 return LValue.After (handler (RValue));
2229 // attDeriv cx (After p1 p2) att =
2230 // after (attDeriv cx p1 att) p2
2231 public override RdpPattern AttDeriv (string name, string ns, string value, XmlReader reader)
2233 return LValue.AttDeriv (name, ns, value, reader).After (RValue);
2236 public override RdpPattern StartAttDeriv (string name, string ns)
2238 RdpPattern handled = LValue.StartAttDeriv (name, ns);
2239 RdpFlip f = MakeFlip (RdpUtil.AfterFunction, RValue);
2240 return handled.ApplyAfter (new RdpApplyAfterHandler (
2244 internal override RdpPattern StartAttDeriv (string name, string ns, MemoizationStore memo)
2246 RdpPattern handled = memo.StartAttDeriv (LValue, name, ns);
2247 RdpFlip f = MakeFlip (RdpUtil.AfterFunction, RValue);
2248 return handled.ApplyAfter (new RdpApplyAfterHandler (
2252 public override RdpPattern EndAttDeriv ()
2254 return LValue.Nullable ? RValue : RdpNotAllowed.Instance;
2257 public override RdpPattern StartTagCloseDeriv ()
2259 return LValue.StartTagCloseDeriv ().After (RValue);
2262 internal override RdpPattern StartTagCloseDeriv (MemoizationStore memo)
2264 return memo.StartTagCloseDeriv (LValue).After (RValue);
2267 public override RdpPattern EndTagDeriv ()
2269 return LValue.Nullable ? RValue : RdpNotAllowed.Instance;
2272 public override RelaxngPatternType PatternType {
2273 get { return RelaxngPatternType.After; }
2276 internal override void MarkReachableDefs ()
2278 throw new InvalidOperationException ();
2281 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
2283 throw new InvalidOperationException ();
2286 internal override bool ContainsText ()
2288 throw new InvalidOperationException ();