2 // Commons.Xml.Relaxng.Derivative.RdpPatterns.cs
\r
5 // Atsushi Enomoto <ginga@kit.hi-ho.ne.jp>
\r
7 // 2003 Atsushi Enomoto "No rights reserved."
\r
9 // Copyright (c) 2004 Novell Inc.
\r
10 // All rights reserved
\r
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;
\r
37 using Commons.Xml.Relaxng;
\r
39 using LabelList = System.Collections.Hashtable;
\r
42 namespace Commons.Xml.Relaxng.Derivative
\r
44 public delegate RdpPattern RdpApplyAfterHandler (RdpPattern p);
\r
47 public abstract class RdpPattern
\r
49 internal bool nullableComputed;
\r
50 internal bool isNullable;
\r
51 Hashtable patternPool;
\r
53 internal string debug ()
\r
55 return RdpUtil.DebugRdpPattern (this, new Hashtable ());
\r
58 public abstract RelaxngPatternType PatternType { get; }
\r
60 public abstract RdpContentType ContentType { get; }
\r
62 private Hashtable setupTable (Type type, RdpPattern p)
\r
65 if (patternPool == null) {
\r
66 patternPool = new Hashtable ();
\r
69 Hashtable typePool = (Hashtable) patternPool [type];
\r
70 if (typePool == null) {
\r
71 typePool = new Hashtable ();
\r
72 patternPool [type] = typePool;
\r
74 Hashtable pTable = (Hashtable) typePool [p];
\r
75 if (pTable == null) {
\r
76 pTable = new Hashtable ();
\r
77 typePool [p] = pTable;
\r
82 public RdpChoice MakeChoice (RdpPattern p1, RdpPattern p2)
\r
84 Hashtable p1Table = setupTable (typeof (RdpChoice), p1);
\r
85 if (p1Table [p2] == null) {
\r
86 RdpChoice c = new RdpChoice (p1, p2);
\r
87 c.setInternTable (this.patternPool);
\r
90 return (RdpChoice) p1Table [p2];
\r
93 public RdpPattern MakeGroup (RdpPattern p1, RdpPattern p2)
\r
95 Hashtable p1Table = setupTable (typeof (RdpGroup), p1);
\r
96 if (p1Table [p2] == null) {
\r
97 RdpGroup g = new RdpGroup (p1, p2);
\r
98 g.setInternTable (this.patternPool);
\r
101 return (RdpGroup) p1Table [p2];
\r
104 public RdpInterleave MakeInterleave (RdpPattern p1, RdpPattern p2)
\r
106 Hashtable p1Table = setupTable (typeof (RdpInterleave), p1);
\r
107 if (p1Table [p2] == null) {
\r
108 RdpInterleave i = new RdpInterleave (p1, p2);
\r
109 i.setInternTable (this.patternPool);
\r
112 return (RdpInterleave) p1Table [p2];
\r
115 public RdpAfter MakeAfter (RdpPattern p1, RdpPattern p2)
\r
117 Hashtable p1Table = setupTable (typeof (RdpAfter), p1);
\r
118 if (p1Table [p2] == null) {
\r
119 RdpAfter a = new RdpAfter (p1, p2);
\r
120 a.setInternTable (this.patternPool);
\r
123 return (RdpAfter) p1Table [p2];
\r
126 public RdpOneOrMore MakeOneOrMore (RdpPattern p)
\r
128 Hashtable p1Table = setupTable (typeof (RdpOneOrMore), p);
\r
129 Hashtable pTable = (Hashtable) patternPool [RelaxngPatternType.OneOrMore];
\r
130 if (pTable == null) {
\r
131 pTable = new Hashtable ();
\r
132 patternPool [RelaxngPatternType.OneOrMore] = pTable;
\r
134 if (pTable [p] == null)
\r
135 pTable [p] = new RdpOneOrMore (p);
\r
136 return (RdpOneOrMore) pTable [p];
\r
139 internal void setInternTable (Hashtable ht)
\r
141 this.patternPool = ht;
\r
143 Hashtable pt = ht [PatternType] as Hashtable;
\r
145 pt = new Hashtable ();
\r
146 ht [PatternType] = pt;
\r
149 RdpAbstractSingleContent single =
\r
150 this as RdpAbstractSingleContent;
\r
151 if (single != null) {
\r
152 if (pt [single.Child] == null) {
\r
153 pt [single.Child] = this;
\r
154 single.Child.setInternTable (ht);
\r
159 RdpAbstractBinary binary =
\r
160 this as RdpAbstractBinary;
\r
161 if (binary != null) {
\r
162 Hashtable lTable = setupTable (GetType (), binary.LValue);
\r
163 if (lTable [binary.RValue] == null) {
\r
164 lTable [binary.RValue] = this;
\r
165 binary.LValue.setInternTable (ht);
\r
166 binary.RValue.setInternTable (ht);
\r
171 // For rest patterns, only check recursively, without pooling.
\r
172 RdpAttribute attr = this as RdpAttribute;
\r
173 if (attr != null) {
\r
174 attr.Children.setInternTable (ht);
\r
177 RdpElement el = this as RdpElement;
\r
179 el.Children.setInternTable (ht);
\r
182 RdpDataExcept dex= this as RdpDataExcept;
\r
184 dex.Except.setInternTable (ht);
\r
188 switch (PatternType) {
\r
189 case RelaxngPatternType.Empty:
\r
190 case RelaxngPatternType.NotAllowed:
\r
191 case RelaxngPatternType.Text:
\r
192 case RelaxngPatternType.Data:
\r
193 case RelaxngPatternType.Value:
\r
197 #if REPLACE_IN_ADVANCE
\r
198 throw new InvalidOperationException ();
\r
202 internal abstract void MarkReachableDefs ();
\r
204 internal abstract void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept);
\r
206 internal virtual void CheckAttributeDuplicates ()
\r
210 internal abstract bool ContainsText ();
\r
212 internal virtual RdpPattern ExpandRef (Hashtable defs)
\r
217 internal virtual RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited)
\r
222 public abstract bool Nullable { get; }
\r
224 // fills QName collection
\r
225 public abstract void GetLabels (LabelList elements, LabelList attributes);
\r
227 internal void AddNameLabel (LabelList names, RdpNameClass nc)
\r
231 RdpName name = nc as RdpName;
\r
232 if (name != null) {
\r
233 XmlQualifiedName qname = new XmlQualifiedName (
\r
234 name.LocalName, name.NamespaceURI);
\r
235 names [qname] = qname;
\r
238 RdpNameClassChoice choice = nc as RdpNameClassChoice;
\r
239 if (choice != null) {
\r
240 AddNameLabel (names, choice.LValue);
\r
241 AddNameLabel (names, choice.RValue);
\r
244 // For NsName and AnyName, do nothing.
\r
248 public virtual RdpPattern TextDeriv (string s, XmlReader reader)
\r
250 // This is an extension to JJC algorithm.
\r
251 // Whitespace text are allowed except for Data and Value
\r
252 // (their TextDeriv are overridden)
\r
253 return Util.IsWhitespace (s) ? this : RdpNotAllowed.Instance;
\r
257 public RdpPattern ChildDeriv (RdpChildNode child)
\r
259 RdpTextChild tc = child as RdpTextChild;
\r
260 // RdpElementChild ec = child as RdpElementChild;
\r
262 return TextDeriv (tc.Text);
\r
264 // complex stuff;-(
\r
265 return StartTagOpenDeriv (ec.LocalName, ec.NamespaceURI)
\r
266 .AttsDeriv (ec.Attributes)
\r
267 .StartTagCloseDeriv ()
\r
268 .ChildrenDeriv (ec.ChildNodes)
\r
274 public RdpPattern ListDeriv (string [] list, int index, XmlReader reader)
\r
276 return listDerivInternal (list, 0, reader);
\r
279 private RdpPattern listDerivInternal (string [] list, int start, XmlReader reader)
\r
281 if (list.Length <= start)
\r
284 return this.TextDeriv (list [start], reader).listDerivInternal (list, start + 1, reader);
\r
288 public virtual RdpPattern Choice (RdpPattern p)
\r
290 if (p is RdpNotAllowed)
\r
292 else if (this is RdpNotAllowed)
\r
295 return MakeChoice (this, p);
\r
299 public virtual RdpPattern Group (RdpPattern p)
\r
301 if (p is RdpNotAllowed || this is RdpNotAllowed)
\r
302 return RdpNotAllowed.Instance;
\r
303 else if (p is RdpEmpty)
\r
305 else if (this is RdpEmpty)
\r
308 return MakeGroup (this, p);
\r
311 // Interleave(this, p)
\r
312 public virtual RdpPattern Interleave (RdpPattern p)
\r
314 if (p is RdpNotAllowed || this is RdpNotAllowed)
\r
315 return RdpNotAllowed.Instance;
\r
316 else if (p is RdpEmpty)
\r
318 else if (this is RdpEmpty)
\r
321 return MakeInterleave (this, p);
\r
325 public virtual RdpPattern After (RdpPattern p)
\r
327 if (this is RdpNotAllowed || p is RdpNotAllowed)
\r
328 return RdpNotAllowed.Instance;
\r
330 return MakeAfter (this, p);
\r
334 // applyAfter((f, p1=this), p2)
\r
335 public virtual RdpPattern ApplyAfter (RdpApplyAfterHandler h)
\r
337 return RdpNotAllowed.Instance;
\r
340 // startTagOpenDeriv (this, qname)
\r
341 // startTagOpenDeriv _ qn = NotAllowed (default)
\r
342 public virtual RdpPattern StartTagOpenDeriv (string name, string ns)
\r
344 return RdpNotAllowed.Instance;
\r
347 // attDeriv(ctx, this, att)
\r
348 // attDeriv _ _ _ = NotAllowed
\r
349 public virtual RdpPattern AttDeriv (string name, string ns, string value, XmlReader reader)
\r
351 return RdpNotAllowed.Instance;
\r
354 public bool ValueMatch (string s, XmlReader reader)
\r
356 return (Nullable && RdpUtil.Whitespace (s)) ||
\r
357 TextDeriv (s, reader).Nullable;
\r
360 public virtual RdpPattern StartTagCloseDeriv ()
\r
366 public RdpPattern ChildrenDeriv (RdpChildNodes children)
\r
368 return childrenDerivInternal (children, 0);
\r
371 RdpPattern childrenDerivInternal (RdpChildNodes children, int start)
\r
373 if (children.Count == 0) {
\r
374 // childrenDeriv cx p []
\r
375 RdpChildNodes c = new RdpChildNodes ();
\r
376 c.Add (new RdpTextChild (String.Empty));
\r
377 return ChildrenDeriv (c);
\r
378 } else if (children.Count == 1 && children [0] is RdpTextChild) {
\r
379 // childrenDeriv cx p [(TextNode s)]
\r
380 RdpTextChild tc = children [0] as RdpTextChild;
\r
381 RdpPattern p1 = ChildDeriv (tc);
\r
382 return RdpUtil.Whitespace (tc.Text) ?
\r
383 RdpUtil.Choice (this, p1) : p1;
\r
385 // childrenDeriv cx p children
\r
386 return stripChildrenDerivInternal (children, start);
\r
389 RdpPattern stripChildrenDerivInternal (RdpChildNodes children, int start)
\r
391 if (children.Count == start)
\r
394 RdpChildNode firstChild =
\r
395 children [start] as RdpChildNode;
\r
397 (firstChild.IsNonWhitespaceText) ?
\r
398 this : ChildDeriv (firstChild);
\r
399 return p.childrenDerivInternal (children, start + 1);
\r
404 public RdpPattern OneOrMore ()
\r
406 if (PatternType == RelaxngPatternType.NotAllowed)
\r
407 return RdpNotAllowed.Instance;
\r
409 return MakeOneOrMore (this);
\r
412 public virtual RdpPattern EndTagDeriv ()
\r
414 return RdpNotAllowed.Instance;
\r
420 public class RdpEmpty : RdpPattern
\r
422 public RdpEmpty () {}
\r
425 instance = new RdpEmpty ();
\r
428 public override bool Nullable {
\r
429 get { return true; }
\r
432 static RdpEmpty instance;
\r
433 public static RdpEmpty Instance {
\r
434 get { return instance; }
\r
437 public override RelaxngPatternType PatternType {
\r
438 get { return RelaxngPatternType.Empty; }
\r
441 public override RdpContentType ContentType {
\r
442 get { return RdpContentType.Empty; }
\r
445 public override void GetLabels (LabelList elements, LabelList attributes)
\r
450 internal override void MarkReachableDefs ()
\r
455 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
\r
458 throw new RelaxngException ("empty cannot appear under except of a data pattern.");
\r
461 internal override bool ContainsText()
\r
468 public class RdpNotAllowed : RdpPattern
\r
470 public RdpNotAllowed () {}
\r
471 static RdpNotAllowed ()
\r
473 instance = new RdpNotAllowed ();
\r
476 static RdpNotAllowed instance;
\r
477 public static RdpNotAllowed Instance {
\r
478 get { return instance; }
\r
481 public override bool Nullable {
\r
482 get { return false; }
\r
485 public override RdpPattern ApplyAfter (RdpApplyAfterHandler h)
\r
487 return RdpNotAllowed.Instance;
\r
490 public override RelaxngPatternType PatternType {
\r
491 get { return RelaxngPatternType.NotAllowed; }
\r
494 public override RdpContentType ContentType {
\r
495 get { return RdpContentType.Empty; }
\r
498 internal override void MarkReachableDefs ()
\r
503 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
\r
508 internal override bool ContainsText()
\r
513 public override void GetLabels (LabelList elements, LabelList attributes)
\r
515 // FIXME: Supposed to clear something here?
\r
520 public class RdpText : RdpPattern
\r
522 static RdpText instance;
\r
523 public static RdpText Instance {
\r
524 get { return instance; }
\r
527 public RdpText () {}
\r
530 instance = new RdpText ();
\r
533 public override bool Nullable {
\r
534 get { return true; }
\r
537 public override RelaxngPatternType PatternType {
\r
538 get { return RelaxngPatternType.Text; }
\r
541 public override RdpContentType ContentType {
\r
542 get { return RdpContentType.Complex; }
\r
545 public override RdpPattern TextDeriv (string s, XmlReader reader)
\r
550 internal override void MarkReachableDefs ()
\r
555 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
\r
558 throw new RelaxngException ("text is not allowed under a list.");
\r
560 throw new RelaxngException ("text is not allowed under except of a list.");
\r
563 internal override bool ContainsText()
\r
568 public override void GetLabels (LabelList elements, LabelList attributes)
\r
575 public abstract class RdpAbstractBinary : RdpPattern
\r
577 public RdpAbstractBinary (RdpPattern l, RdpPattern r)
\r
584 public RdpPattern LValue {
\r
590 public RdpPattern RValue {
\r
595 public override RdpContentType ContentType {
\r
597 if (l.ContentType == RdpContentType.Empty)
\r
598 return r.ContentType;
\r
599 if (r.ContentType == RdpContentType.Empty)
\r
600 return l.ContentType;
\r
602 if ((l.ContentType & RdpContentType.Simple) != 0 || ((r.ContentType & RdpContentType.Simple) != 0))
\r
603 throw new RelaxngException ("The content type of this group is invalid.");
\r
604 return RdpContentType.Complex;
\r
609 internal override RdpPattern ExpandRef (Hashtable defs)
\r
612 l = l.ExpandRef (defs);
\r
613 r = r.ExpandRef (defs);
\r
618 internal override RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited)
\r
620 if (visited.Contains (this))
\r
622 visited.Add (this, this);
\r
624 if (LValue.PatternType == RelaxngPatternType.NotAllowed ||
\r
625 RValue.PatternType == RelaxngPatternType.NotAllowed) {
\r
627 return RdpNotAllowed.Instance;
\r
628 } else if (LValue.PatternType == RelaxngPatternType.Empty) {
\r
630 return RValue.ReduceEmptyAndNotAllowed (ref result, visited);
\r
631 } else if (RValue.PatternType == RelaxngPatternType.Empty) {
\r
633 return LValue.ReduceEmptyAndNotAllowed (ref result, visited);
\r
635 LValue = LValue.ReduceEmptyAndNotAllowed (ref result, visited);
\r
636 RValue = RValue.ReduceEmptyAndNotAllowed (ref result, visited);
\r
641 internal override void MarkReachableDefs ()
\r
643 l.MarkReachableDefs ();
\r
644 r.MarkReachableDefs ();
\r
647 internal override bool ContainsText()
\r
649 return l.ContainsText () || r.ContainsText ();
\r
652 internal override void CheckAttributeDuplicates ()
\r
654 LValue.CheckAttributeDuplicates ();
\r
655 RValue.CheckAttributeDuplicates ();
\r
659 internal void CheckAttributeDuplicatesCore ()
\r
661 // expecting all items are interned
\r
662 bool checkAttributes = false;
\r
663 Hashtable lc = new Hashtable ();
\r
664 LValue.GetLabels (null, lc);
\r
668 Hashtable rc = new Hashtable ();
\r
669 RValue.GetLabels (null, rc);
\r
673 foreach (XmlQualifiedName name in lc.Values)
\r
674 if (rc.Contains (name))
\r
675 throw new RelaxngException ("Duplicate attributes inside a group or an interleave is not allowed.");
\r
680 public class RdpChoice : RdpAbstractBinary
\r
682 public RdpChoice (RdpPattern l, RdpPattern r) : base (l, r)
\r
686 public override bool Nullable {
\r
688 if (!nullableComputed) {
\r
690 LValue.Nullable || RValue.Nullable;
\r
691 nullableComputed = true;
\r
697 public override RelaxngPatternType PatternType {
\r
698 get { return RelaxngPatternType.Choice; }
\r
701 public override RdpContentType ContentType {
\r
703 if (LValue.ContentType == RdpContentType.Simple ||
\r
704 RValue.ContentType == RdpContentType.Simple)
\r
705 return RdpContentType.Simple;
\r
706 return base.ContentType;
\r
710 public override void GetLabels (LabelList elements, LabelList attributes)
\r
712 LValue.GetLabels (elements, attributes);
\r
713 RValue.GetLabels (elements, attributes);
\r
717 internal override RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited)
\r
719 if (visited.Contains (this))
\r
721 visited.Add (this, this);
\r
723 if (LValue.PatternType == RelaxngPatternType.NotAllowed &&
\r
724 RValue.PatternType == RelaxngPatternType.NotAllowed) {
\r
726 return RdpNotAllowed.Instance;
\r
727 } else if (LValue.PatternType == RelaxngPatternType.NotAllowed) {
\r
729 return RValue.ReduceEmptyAndNotAllowed (ref result, visited);
\r
730 } else if (RValue.PatternType == RelaxngPatternType.NotAllowed) {
\r
732 return LValue.ReduceEmptyAndNotAllowed (ref result, visited);
\r
733 } else if (LValue.PatternType == RelaxngPatternType.Empty &&
\r
734 RValue.PatternType == RelaxngPatternType.Empty) {
\r
736 return RdpEmpty.Instance;
\r
737 } else if (RValue.PatternType == RelaxngPatternType.Empty) {
\r
739 RValue = LValue.ReduceEmptyAndNotAllowed (ref result, visited);
\r
740 LValue = RdpEmpty.Instance;
\r
743 LValue = LValue.ReduceEmptyAndNotAllowed (ref result, visited);
\r
744 RValue = RValue.ReduceEmptyAndNotAllowed (ref result, visited);
\r
749 public override RdpPattern TextDeriv (string s, XmlReader reader)
\r
751 return LValue.TextDeriv (s, reader).Choice (RValue.TextDeriv (s, reader));
\r
754 public override RdpPattern ApplyAfter (RdpApplyAfterHandler handler)
\r
756 // return handler (LValue).Choice (handler (RValue));
\r
757 return LValue.ApplyAfter (handler).Choice (RValue.ApplyAfter (handler));
\r
760 public override RdpPattern StartTagOpenDeriv (string name, string ns)
\r
763 return RdpUtil.Choice (
\r
764 RdpUtil.StartTagOpenDeriv (LValue, qname),
\r
765 RdpUtil.StartTagOpenDeriv (RValue, qname));
\r
767 RdpPattern lDeriv = LValue.StartTagOpenDeriv (name, ns);
\r
768 return lDeriv.Choice (RValue.StartTagOpenDeriv (name, ns));
\r
772 // attDeriv cx (Choice p1 p2) att =
\r
773 // choice (attDeriv cx p1 att) (attDeriv cx p2 att)
\r
774 public override RdpPattern AttDeriv (string name, string ns, string value, XmlReader reader)
\r
776 return LValue.AttDeriv (name, ns, value, reader)
\r
777 .Choice (RValue.AttDeriv (name, ns, value, reader));
\r
780 // startTagCloseDeriv (Choice p1 p2) =
\r
781 // choice (startTagCloseDeriv p1) (startTagCloseDeriv p2)
\r
782 public override RdpPattern StartTagCloseDeriv ()
\r
784 return LValue.StartTagCloseDeriv ()
\r
785 .Choice (RValue.StartTagCloseDeriv ());
\r
788 public override RdpPattern EndTagDeriv ()
\r
790 return LValue.EndTagDeriv ().Choice (RValue.EndTagDeriv ());
\r
793 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
\r
795 LValue.CheckConstraints (attribute, oneOrMore, oneOrMoreGroup, oneOrMoreInterleave, list, dataExcept);
\r
796 RValue.CheckConstraints (attribute, oneOrMore, oneOrMoreGroup, oneOrMoreInterleave, list, dataExcept);
\r
801 public class RdpInterleave : RdpAbstractBinary
\r
803 public RdpInterleave (RdpPattern l, RdpPattern r) : base (l, r)
\r
807 public override bool Nullable {
\r
809 if (!nullableComputed) {
\r
811 LValue.Nullable && RValue.Nullable;
\r
812 nullableComputed = true;
\r
818 public override void GetLabels (LabelList elements, LabelList attributes)
\r
820 LValue.GetLabels (elements, attributes);
\r
821 RValue.GetLabels (elements, attributes);
\r
824 internal override RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited)
\r
826 if (visited.Contains (this))
\r
828 visited.Add (this, this);
\r
830 if (LValue.PatternType == RelaxngPatternType.NotAllowed ||
\r
831 RValue.PatternType == RelaxngPatternType.NotAllowed) {
\r
833 return RdpNotAllowed.Instance;
\r
835 LValue = LValue.ReduceEmptyAndNotAllowed (ref result, visited);
\r
836 RValue = RValue.ReduceEmptyAndNotAllowed (ref result, visited);
\r
841 public override RdpPattern TextDeriv (string s, XmlReader reader)
\r
843 return LValue.TextDeriv (s, reader).Interleave (RValue)
\r
844 .Choice (LValue.Interleave (RValue.TextDeriv (s, reader)));
\r
847 // => choice (applyAfter (flip interleave p2) (startTagOpenDeriv p1 qn)) (applyAfter (interleave p1) (startTagOpenDeriv p2 qn)
\r
848 // => p1.startTagOpenDeriv(qn).applyAfter (flip interleave p2).choice (p2.startTagOpenDeriv(qn).applyAfter (interleave p1) )
\r
849 public override RdpPattern StartTagOpenDeriv (string name, string ns)
\r
851 RdpPattern handledL = LValue.StartTagOpenDeriv (name, ns);
\r
852 RdpPattern handledR = RValue.StartTagOpenDeriv (name, ns);
\r
853 RdpFlip flipL = new RdpFlip (new RdpBinaryFunction (RdpUtil.Interleave), RValue);
\r
854 RdpPattern choiceL = handledL.ApplyAfter (new RdpApplyAfterHandler (flipL.Apply));
\r
855 RdpPattern choiceR = handledR.ApplyAfter (new RdpApplyAfterHandler (LValue.Interleave));
\r
856 return choiceL.Choice (choiceR);
\r
859 // attDeriv cx (Interleave p1 p2) att =
\r
860 // choice (interleave (attDeriv cx p1 att) p2)
\r
861 // (interleave p1 (attDeriv cx p2 att))
\r
862 public override RdpPattern AttDeriv (string name, string ns, string value, XmlReader reader)
\r
864 return LValue.AttDeriv (name, ns, value, reader)
\r
865 .Interleave (RValue)
\r
866 .Choice (LValue.Interleave (
\r
867 RValue.AttDeriv (name, ns, value, reader)));
\r
870 // startTagCloseDeriv (Interleave p1 p2) =
\r
871 // interleave (startTagCloseDeriv p1) (startTagCloseDeriv p2)
\r
872 public override RdpPattern StartTagCloseDeriv ()
\r
874 return LValue.StartTagCloseDeriv ()
\r
875 .Interleave (RValue.StartTagCloseDeriv ());
\r
879 // FIXME: This is not specified in James Clark's algorithm, so
\r
880 // this may raise unstable behaviour!!
\r
881 // I think this is right but not confident.
\r
883 // ... then I reminded to include it.
\r
884 public override RdpPattern EndTagDeriv ()
\r
886 return LValue.Nullable ? RValue : RdpNotAllowed.Instance;
\r
890 public override RelaxngPatternType PatternType {
\r
891 get { return RelaxngPatternType.Interleave; }
\r
894 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
\r
897 throw new RelaxngException ("interleave is not allowed under a list.");
\r
899 throw new RelaxngException ("interleave is not allowed under except of a data.");
\r
902 LValue.CheckConstraints (attribute, oneOrMore, oneOrMoreGroup, oneOrMore, list, dataExcept);
\r
903 RValue.CheckConstraints (attribute, oneOrMore, oneOrMoreGroup, oneOrMore, list, dataExcept);
\r
906 // TODO: (1) unique name analysis
\r
907 // (2) text/text prohibited
\r
908 if (LValue.PatternType == RelaxngPatternType.Text && RValue.PatternType == RelaxngPatternType.Text)
\r
909 throw new RelaxngException ("Both branches of the interleave contains a text pattern.");
\r
913 internal override void CheckAttributeDuplicates ()
\r
915 base.CheckAttributeDuplicates ();
\r
916 CheckAttributeDuplicatesCore ();
\r
921 public class RdpGroup : RdpAbstractBinary
\r
923 public RdpGroup (RdpPattern l, RdpPattern r) : base (l, r)
\r
927 public override bool Nullable {
\r
929 if (!nullableComputed) {
\r
931 LValue.Nullable && RValue.Nullable;
\r
932 nullableComputed = true;
\r
938 public override void GetLabels (LabelList elements, LabelList attributes)
\r
940 LValue.GetLabels (elements, attributes);
\r
941 if (LValue.Nullable)
\r
942 RValue.GetLabels (elements, attributes);
\r
944 RValue.GetLabels (null, attributes);
\r
947 public override RdpPattern TextDeriv (string s, XmlReader reader)
\r
949 RdpPattern p = LValue.TextDeriv (s, reader).Group (RValue);
\r
950 return LValue.Nullable ?
\r
951 p.Choice (RValue.TextDeriv(s, reader)) : p;
\r
954 // startTagOpenDeriv (Group p1 p2) qn =
\r
955 // let x = applyAfter (flip group p2) (startTagOpenDeriv p1 qn)
\r
956 // in if nullable p1 then
\r
957 // choice x (startTagOpenDeriv p2 qn)
\r
960 public override RdpPattern StartTagOpenDeriv (string name, string ns)
\r
962 RdpPattern handled = LValue.StartTagOpenDeriv (name, ns);
\r
963 RdpFlip f = new RdpFlip (new RdpBinaryFunction (RdpUtil.Group), RValue);
\r
964 RdpPattern x = handled.ApplyAfter (new RdpApplyAfterHandler (f.Apply));
\r
965 if (LValue.Nullable)
\r
966 return x.Choice (RValue.StartTagOpenDeriv (name, ns));
\r
971 // attDeriv cx (Group p1 p2) att =
\r
972 // choice (group (attDeriv cx p1 att) p2)
\r
973 // (group p1 (attDeriv cx p2 att))
\r
974 public override RdpPattern AttDeriv (string name, string ns, string value, XmlReader reader)
\r
976 return LValue.AttDeriv (name, ns, value, reader).Group (RValue)
\r
977 .Choice (LValue.Group (
\r
978 RValue.AttDeriv (name, ns, value, reader)));
\r
981 // startTagCloseDeriv (Group p1 p2) =
\r
982 // group (startTagCloseDeriv p1) (startTagCloseDeriv p2)
\r
983 public override RdpPattern StartTagCloseDeriv ()
\r
985 return LValue.StartTagCloseDeriv ()
\r
986 .Group (RValue.StartTagCloseDeriv ());
\r
989 public override RelaxngPatternType PatternType {
\r
990 get { return RelaxngPatternType.Group; }
\r
993 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
\r
996 throw new RelaxngException ("interleave is not allowed under except of a data.");
\r
998 LValue.CheckConstraints (attribute, oneOrMore, oneOrMore, oneOrMoreInterleave, list, dataExcept);
\r
999 RValue.CheckConstraints (attribute, oneOrMore, oneOrMore, oneOrMoreInterleave, list, dataExcept);
\r
1003 internal override void CheckAttributeDuplicates ()
\r
1005 base.CheckAttributeDuplicates ();
\r
1006 CheckAttributeDuplicatesCore ();
\r
1010 public abstract class RdpAbstractSingleContent : RdpPattern
\r
1015 internal override RdpPattern ExpandRef (Hashtable defs)
\r
1018 child = child.ExpandRef (defs);
\r
1022 public RdpAbstractSingleContent (RdpPattern p)
\r
1027 public RdpPattern Child {
\r
1028 get { return child; }
\r
1029 set { child = value; }
\r
1032 internal override void MarkReachableDefs ()
\r
1034 child.MarkReachableDefs ();
\r
1037 internal override bool ContainsText()
\r
1039 return child.ContainsText ();
\r
1042 internal override void CheckAttributeDuplicates ()
\r
1044 child.CheckAttributeDuplicates ();
\r
1049 public class RdpOneOrMore : RdpAbstractSingleContent
\r
1051 public RdpOneOrMore (RdpPattern p) : base (p)
\r
1055 public override RelaxngPatternType PatternType {
\r
1056 get { return RelaxngPatternType.OneOrMore; }
\r
1059 public override RdpContentType ContentType {
\r
1061 if (Child.ContentType == RdpContentType.Simple)
\r
1062 throw new RelaxngException ("Invalid content type was found.");
\r
1063 return Child.ContentType;
\r
1067 public override bool Nullable {
\r
1068 get { return Child.Nullable; }
\r
1071 public override void GetLabels (LabelList elements, LabelList attributes)
\r
1073 Child.GetLabels (elements, attributes);
\r
1076 internal override RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited)
\r
1078 if (visited.Contains (this))
\r
1080 visited.Add (this, this);
\r
1082 if (Child.PatternType == RelaxngPatternType.NotAllowed) {
\r
1084 return RdpNotAllowed.Instance;
\r
1085 } else if (Child.PatternType == RelaxngPatternType.Empty)
\r
1086 return RdpEmpty.Instance;
\r
1088 Child = Child.ReduceEmptyAndNotAllowed (ref result, visited);
\r
1093 public override RdpPattern TextDeriv (string s, XmlReader reader)
\r
1095 return Child.TextDeriv (s, reader).Group (Choice (RdpEmpty.Instance));
\r
1098 // attDeriv cx (OneOrMore p) att =
\r
1099 // group (attDeriv cx p att) (choice (OneOrMore p) Empty)
\r
1100 public override RdpPattern AttDeriv (string name, string ns, string value, XmlReader reader)
\r
1103 return RdpUtil.Group (
\r
1104 RdpUtil.AttDeriv (ctx, children, att),
\r
1105 RdpUtil.Choice (RdpUtil.OneOrMore (children), RdpEmpty.Instance));
\r
1107 return Child.AttDeriv (name, ns, value, reader)
\r
1108 .Group (Choice (RdpEmpty.Instance));
\r
1112 // startTagOpenDeriv (OneOrMore p) qn =
\r
1113 // applyAfter (flip group (choice (OneOrMore p) Empty))
\r
1114 // (startTagOpenDeriv p qn)
\r
1115 public override RdpPattern StartTagOpenDeriv (string name, string ns)
\r
1117 RdpPattern rest = RdpEmpty.Instance.Choice (Child.OneOrMore ());
\r
1118 RdpPattern handled = Child.StartTagOpenDeriv (name, ns);
\r
1119 RdpFlip f = new RdpFlip (new RdpBinaryFunction (RdpUtil.Group), rest);
\r
1120 return handled.ApplyAfter (new RdpApplyAfterHandler (f.Apply));
\r
1123 // startTagCloseDeriv (OneOrMore p) =
\r
1124 // oneOrMore (startTagCloseDeriv p)
\r
1125 public override RdpPattern StartTagCloseDeriv ()
\r
1128 return RdpUtil.OneOrMore (
\r
1129 RdpUtil.StartTagCloseDeriv (children));
\r
1131 return Child.StartTagCloseDeriv ().OneOrMore ();
\r
1135 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
\r
1138 throw new RelaxngException ("oneOrMore is not allowed under except of a data.");
\r
1139 this.Child.CheckConstraints (attribute, true, oneOrMoreGroup, oneOrMoreInterleave, list, dataExcept);
\r
1144 public class RdpList : RdpAbstractSingleContent
\r
1146 public RdpList (RdpPattern p) : base (p)
\r
1150 internal override RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited)
\r
1152 if (visited.Contains (this))
\r
1154 visited.Add (this, this);
\r
1156 if (Child.PatternType == RelaxngPatternType.NotAllowed) {
\r
1158 return RdpNotAllowed.Instance;
\r
1160 Child = Child.ReduceEmptyAndNotAllowed (ref result, visited);
\r
1166 // This is not written in James Clark's derivative algorithm
\r
1167 // ( http://www.thaiopensource.com/relaxng/derivative.html ),
\r
1168 // but it looks required.
\r
1169 public override bool Nullable {
\r
1170 get { return this.Child.Nullable; }
\r
1173 // ... but it also causes different error:
\r
1174 // <list><group><data .../><data .../></group></list>
\r
1176 public override bool Nullable {
\r
1177 get { return false; }
\r
1180 public override RelaxngPatternType PatternType {
\r
1181 get { return RelaxngPatternType.List; }
\r
1184 public override RdpContentType ContentType {
\r
1185 get { return RdpContentType.Simple; }
\r
1188 public override void GetLabels (LabelList elements, LabelList attributes)
\r
1190 Child.GetLabels (elements, attributes);
\r
1193 public override RdpPattern TextDeriv (string s, XmlReader reader)
\r
1195 RdpPattern p = Child.ListDeriv (Util.NormalizeWhitespace (s).Split (RdpUtil.WhitespaceChars), 0, reader);
\r
1197 return RdpEmpty.Instance;
\r
1199 return RdpNotAllowed.Instance;
\r
1202 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
\r
1205 throw new RelaxngException ("list is not allowed uner another list.");
\r
1207 throw new RelaxngException ("list is not allowed under except of a data.");
\r
1208 this.Child.CheckConstraints (attribute, oneOrMore, oneOrMoreGroup, oneOrMoreInterleave, true, dataExcept);
\r
1213 public class RdpData : RdpPattern
\r
1215 public RdpData (RdpDatatype dt)
\r
1221 public RdpDatatype Datatype {
\r
1222 get { return dt; }
\r
1225 // This is not written in James Clark's derivative algorithm
\r
1226 // ( http://www.thaiopensource.com/relaxng/derivative.html ),
\r
1227 // but it looks required.
\r
1228 public override bool Nullable {
\r
1230 if (dt.NamespaceURI.Length == 0)
\r
1236 public override RelaxngPatternType PatternType {
\r
1237 get { return RelaxngPatternType.Data; }
\r
1240 public override RdpContentType ContentType {
\r
1241 get { return RdpContentType.Simple; }
\r
1244 public override void GetLabels (LabelList elements, LabelList attributes)
\r
1249 public override RdpPattern TextDeriv (string s, XmlReader reader)
\r
1251 if (dt.IsAllowed (s, reader))
\r
1252 return RdpEmpty.Instance;
\r
1254 return RdpNotAllowed.Instance;
\r
1257 internal override void MarkReachableDefs ()
\r
1262 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
\r
1267 internal override bool ContainsText()
\r
1274 public class RdpDataExcept : RdpData
\r
1276 public RdpDataExcept (RdpDatatype dt, RdpPattern except)
\r
1279 this.except = except;
\r
1282 RdpPattern except;
\r
1283 public RdpPattern Except {
\r
1284 get { return except; }
\r
1285 set { except = value; }
\r
1288 public override RelaxngPatternType PatternType {
\r
1289 get { return RelaxngPatternType.DataExcept; }
\r
1292 public override RdpContentType ContentType {
\r
1294 RdpContentType c = except.ContentType; // conformance required for except pattern.
\r
1295 return RdpContentType.Simple;
\r
1299 internal override RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited)
\r
1301 if (visited.Contains (this))
\r
1303 visited.Add (this, this);
\r
1305 if (except.PatternType == RelaxngPatternType.NotAllowed) {
\r
1307 return new RdpData (this.Datatype);
\r
1309 except = except.ReduceEmptyAndNotAllowed (ref result, visited);
\r
1314 public override RdpPattern TextDeriv (string s, XmlReader reader)
\r
1316 if (Datatype.IsAllowed (s, reader) && !except.TextDeriv (s, reader).Nullable)
\r
1317 return RdpEmpty.Instance;
\r
1319 return RdpNotAllowed.Instance;
\r
1322 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
\r
1324 this.except.CheckConstraints (attribute, oneOrMore, oneOrMoreGroup, oneOrMoreInterleave, list, true);
\r
1327 internal override bool ContainsText()
\r
1329 return except.ContainsText ();
\r
1334 public class RdpValue : RdpPattern
\r
1336 public RdpValue (RdpDatatype dt, string value)
\r
1339 this.value = value;
\r
1343 public RdpDatatype Datatype {
\r
1344 get { return dt; }
\r
1348 public string Value {
\r
1349 get { return value; }
\r
1352 // This is not written in James Clark's derivative algorithm
\r
1353 // ( http://www.thaiopensource.com/relaxng/derivative.html ),
\r
1354 // but it looks required.
\r
1355 public override bool Nullable {
\r
1357 if (dt.NamespaceURI.Length == 0 && value.Length == 0)
\r
1363 public override RelaxngPatternType PatternType {
\r
1364 get { return RelaxngPatternType.Value; }
\r
1367 public override RdpContentType ContentType {
\r
1368 get { return RdpContentType.Simple; }
\r
1371 public override void GetLabels (LabelList elements, LabelList attributes)
\r
1376 public override RdpPattern TextDeriv (string s, XmlReader reader)
\r
1378 if (dt.IsTypeEqual (value, s, reader))
\r
1379 return RdpEmpty.Instance;
\r
1381 return RdpNotAllowed.Instance;
\r
1384 internal override void MarkReachableDefs ()
\r
1389 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
\r
1391 // nothing to be checked
\r
1394 internal override bool ContainsText()
\r
1401 public class RdpAttribute : RdpPattern
\r
1403 public RdpAttribute (RdpNameClass nameClass, RdpPattern p)
\r
1405 this.nameClass = nameClass;
\r
1406 this.children = p;
\r
1409 RdpNameClass nameClass;
\r
1410 public RdpNameClass NameClass {
\r
1411 get { return nameClass; }
\r
1414 RdpPattern children;
\r
1415 public RdpPattern Children {
\r
1416 get { return children; }
\r
1417 set { children = value; }
\r
1420 public override bool Nullable {
\r
1421 get { return false; }
\r
1424 public override RelaxngPatternType PatternType {
\r
1425 get { return RelaxngPatternType.Attribute; }
\r
1428 public override RdpContentType ContentType {
\r
1429 get { return RdpContentType.Empty; }
\r
1432 public override void GetLabels (LabelList elements, LabelList attributes)
\r
1434 AddNameLabel (attributes, NameClass);
\r
1438 internal override RdpPattern ExpandRef (Hashtable defs)
\r
1440 if (!isExpanded) {
\r
1441 isExpanded = true;
\r
1442 children = children.ExpandRef (defs);
\r
1447 internal override RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited)
\r
1449 if (visited.Contains (this))
\r
1451 visited.Add (this, this);
\r
1453 if (children.PatternType == RelaxngPatternType.NotAllowed) {
\r
1455 return RdpNotAllowed.Instance;
\r
1457 children = children.ReduceEmptyAndNotAllowed (ref result, visited);
\r
1462 // attDeriv cx (Attribute nc p) (AttributeNode qn s) =
\r
1463 // if contains nc qn && valueMatch cx p s then Empty else NotAllowed
\r
1464 public override RdpPattern AttDeriv (string name, string ns, string value, XmlReader reader)
\r
1466 // If value is null, then does not check ValueMatch.
\r
1468 if (RdpUtil.Contains (this.nameClass, att.QName)
\r
1469 && (value == null || RdpUtil.ValueMatch (ctx, this.children, att.Value)))
\r
1470 return RdpEmpty.Instance;
\r
1472 return RdpNotAllowed.Instance;
\r
1474 if (nameClass.Contains (name, ns) &&
\r
1475 (value == null || children.ValueMatch (value, reader)))
\r
1476 return RdpEmpty.Instance;
\r
1478 return RdpNotAllowed.Instance;
\r
1482 // startTagCloseDeriv (Attribute _ _) = NotAllowed
\r
1483 public override RdpPattern StartTagCloseDeriv ()
\r
1485 return RdpNotAllowed.Instance;
\r
1488 internal override void MarkReachableDefs ()
\r
1490 children.MarkReachableDefs ();
\r
1493 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
\r
1495 if (attribute || oneOrMoreGroup || oneOrMoreInterleave || list || dataExcept)
\r
1496 throw new RelaxngException ("Not allowed attribute occurence was specified in the pattern.");
\r
1497 this.Children.CheckConstraints (true, oneOrMore, false, false, false, false);
\r
1500 internal override bool ContainsText()
\r
1502 return children.ContainsText ();
\r
1507 public class RdpElement : RdpPattern
\r
1509 public RdpElement (RdpNameClass nameClass, RdpPattern p)
\r
1511 this.nameClass = nameClass;
\r
1512 this.children = p;
\r
1515 RdpNameClass nameClass;
\r
1516 public RdpNameClass NameClass {
\r
1517 get { return nameClass; }
\r
1520 RdpPattern children;
\r
1521 public RdpPattern Children {
\r
1522 get { return children; }
\r
1523 set { children = value; }
\r
1526 public override bool Nullable {
\r
1527 get { return false; }
\r
1530 public override RelaxngPatternType PatternType {
\r
1531 get { return RelaxngPatternType.Element; }
\r
1534 bool contentTypeCheckDone;
\r
1535 public override RdpContentType ContentType {
\r
1537 if (!contentTypeCheckDone) {
\r
1538 contentTypeCheckDone = true;
\r
1539 RdpContentType ct = children.ContentType; // conformance required.
\r
1541 return RdpContentType.Complex;
\r
1545 public override void GetLabels (LabelList elements, LabelList attributes)
\r
1547 AddNameLabel (elements, NameClass);
\r
1552 short expanding; // FIXME: It is totally not required, but there is
\r
1553 // some bugs in simplification and without it it causes infinite loop.
\r
1554 internal override RdpPattern ExpandRef (Hashtable defs)
\r
1556 if (!isExpanded) {
\r
1557 isExpanded = true;
\r
1558 if (expanding == 100)
\r
1559 throw new RelaxngException (String.Format ("Invalid recursion was found. Name is {0}", nameClass));
\r
1561 children = children.ExpandRef (defs);
\r
1567 internal override RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited)
\r
1569 if (visited.Contains (this))
\r
1571 visited.Add (this, this);
\r
1573 children = children.ReduceEmptyAndNotAllowed (ref result, visited);
\r
1577 public override RdpPattern StartTagOpenDeriv (string name, string ns)
\r
1580 if (RdpUtil.Contains (this.nameClass, qname))
\r
1581 return RdpUtil.After (this.Children, RdpEmpty.Instance);
\r
1583 return RdpNotAllowed.Instance;
\r
1585 return nameClass.Contains (name, ns) ?
\r
1586 children.After (RdpEmpty.Instance) :
\r
1587 RdpNotAllowed.Instance;
\r
1591 internal override void MarkReachableDefs ()
\r
1593 children.MarkReachableDefs ();
\r
1596 bool constraintsChecked;
\r
1597 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
\r
1599 if (constraintsChecked)
\r
1601 constraintsChecked = true;
\r
1602 if (attribute || list || dataExcept)
\r
1603 throw new RelaxngException ("Not allowed element occurence was specified in the pattern.");
\r
1604 this.Children.CheckConstraints (false, oneOrMore, oneOrMoreGroup, oneOrMoreInterleave, false, false);
\r
1607 internal override bool ContainsText()
\r
1609 return children.ContainsText ();
\r
1612 internal override void CheckAttributeDuplicates ()
\r
1614 children.CheckAttributeDuplicates ();
\r
1619 public class RdpAfter : RdpAbstractBinary
\r
1621 public RdpAfter (RdpPattern l, RdpPattern r) : base (l, r)
\r
1625 public override bool Nullable {
\r
1626 get { return false; }
\r
1629 public override void GetLabels (LabelList elements, LabelList attributes)
\r
1631 LValue.GetLabels (elements, attributes);
\r
1634 public override RdpPattern TextDeriv (string s, XmlReader reader)
\r
1636 return LValue.TextDeriv (s, reader).After (RValue);
\r
1639 // startTagOpenDeriv (After p1 p2) qn =
\r
1640 // applyAfter (flip after p2) (startTagOpenDeriv p1 qn)
\r
1641 public override RdpPattern StartTagOpenDeriv (string name, string ns)
\r
1643 RdpPattern handled = LValue.StartTagOpenDeriv (name, ns);
\r
1644 RdpFlip f = new RdpFlip (new RdpBinaryFunction (RdpUtil.After), RValue);
\r
1645 return handled.ApplyAfter (new RdpApplyAfterHandler (
\r
1649 public override RdpPattern ApplyAfter (RdpApplyAfterHandler handler)
\r
1651 return LValue.After (handler (RValue));
\r
1654 // attDeriv cx (After p1 p2) att =
\r
1655 // after (attDeriv cx p1 att) p2
\r
1656 public override RdpPattern AttDeriv (string name, string ns, string value, XmlReader reader)
\r
1658 return LValue.AttDeriv (name, ns, value, reader).After (RValue);
\r
1661 public override RdpPattern StartTagCloseDeriv ()
\r
1663 return LValue.StartTagCloseDeriv ().After (RValue);
\r
1666 public override RdpPattern EndTagDeriv ()
\r
1668 return LValue.Nullable ? RValue : RdpNotAllowed.Instance;
\r
1671 public override RelaxngPatternType PatternType {
\r
1672 get { return RelaxngPatternType.After; }
\r
1675 internal override void MarkReachableDefs ()
\r
1677 throw new InvalidOperationException ();
\r
1680 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)
\r
1682 throw new InvalidOperationException ();
\r
1685 internal override bool ContainsText ()
\r
1687 throw new InvalidOperationException ();
\r