1 // 2 // Commons.Xml.Relaxng.Derivative.RdpPatterns.cs 3 // 4 // Author: 5 // Atsushi Enomoto <ginga@kit.hi-ho.ne.jp> 6 // 7 // 2003 Atsushi Enomoto "No rights reserved." 8 // 9 // Copyright (c) 2004 Novell Inc. 10 // All rights reserved 11 // 12 13 // 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: 21 // 22 // The above copyright notice and this permission notice shall be 23 // included in all copies or substantial portions of the Software. 24 // 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. 32 // 33 34 using System; 35 using System.Collections; 36 using System.Xml; 37 using Commons.Xml.Relaxng; 38 39 using LabelList = System.Collections.Hashtable; 40 41 42 namespace Commons.Xml.Relaxng.Derivative 43 { RdpApplyAfterHandler(RdpPattern p)44 public delegate RdpPattern RdpApplyAfterHandler (RdpPattern p); 45 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 48 // for now). 49 public abstract class RdpPattern 50 { 51 public static readonly RdpPattern Anything; 52 RdpPattern()53 static RdpPattern () 54 { 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; 59 } 60 61 internal bool nullableComputed; 62 internal bool isNullable; 63 Hashtable patternPool; 64 debug()65 internal string debug () 66 { 67 return RdpUtil.DebugRdpPattern (this, new Hashtable ()); 68 } 69 70 public abstract RelaxngPatternType PatternType { get; } 71 72 public abstract RdpContentType ContentType { get; } 73 setupTable(Type type, RdpPattern p)74 private Hashtable setupTable (Type type, RdpPattern p) 75 { 76 if (patternPool == null) // could be null for RdpElement etc. 77 patternPool = new Hashtable (); 78 79 Hashtable typePool = (Hashtable) patternPool [type]; 80 if (typePool == null) { 81 typePool = new Hashtable (); 82 patternPool [type] = typePool; 83 } 84 Hashtable pTable = (Hashtable) typePool [p]; 85 if (pTable == null) { 86 pTable = new Hashtable (); 87 typePool [p] = pTable; 88 } 89 return pTable; 90 } 91 MakeFlip(RdpBinaryFunction func, RdpPattern p)92 internal RdpFlip MakeFlip (RdpBinaryFunction func, RdpPattern p) 93 { 94 if (patternPool == null) // could be null for RdpElement etc. 95 patternPool = new Hashtable (); 96 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. 100 101 Hashtable table = patternPool [func] as Hashtable; 102 if (table == null) { 103 table = new Hashtable (); 104 patternPool [func] = table; 105 } 106 RdpFlip f = table [p] as RdpFlip; 107 if (f != null) 108 return f; 109 f = new RdpFlip (func, p); 110 table [p] = f; 111 return f; 112 } 113 MakeChoiceLeaf(RdpPattern p)114 public RdpChoice MakeChoiceLeaf (RdpPattern p) 115 { 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; 122 } 123 RdpChoice leaf = leaves [p] as RdpChoice; 124 if (leaf == null) { 125 leaf = new RdpChoice (RdpEmpty.Instance, p); 126 leaf.setInternTable (patternPool); 127 leaves [p] = leaf; 128 } 129 return leaf; 130 } 131 MakeChoice(RdpPattern p1, RdpPattern p2)132 public RdpPattern MakeChoice (RdpPattern p1, RdpPattern p2) 133 { 134 if (p1.PatternType == RelaxngPatternType.NotAllowed) 135 return p2; 136 if (p2.PatternType == RelaxngPatternType.NotAllowed) 137 return p1; 138 if (p1 == p2) 139 return p1; 140 // choice-leaves support 141 if (p1.PatternType == RelaxngPatternType.Empty) 142 return MakeChoiceLeaf (p2); 143 if (p2.PatternType == RelaxngPatternType.Empty) 144 return MakeChoiceLeaf (p1); 145 146 if (p1.GetHashCode () > p2.GetHashCode ()) { 147 RdpPattern tmp = p1; 148 p1 = p2; 149 p2 = tmp; 150 } 151 152 Hashtable p1Table = setupTable (typeof (RdpChoice), p1); 153 if (p1Table [p2] == null) { 154 RdpChoice c = new RdpChoice (p1, p2); 155 c.setInternTable (this.patternPool); 156 p1Table [p2] = c; 157 } 158 return (RdpChoice) p1Table [p2]; 159 } 160 MakeGroup(RdpPattern p1, RdpPattern p2)161 public RdpPattern MakeGroup (RdpPattern p1, RdpPattern p2) 162 { 163 if (p1.PatternType == RelaxngPatternType.Empty) 164 return p2; 165 166 Hashtable p1Table = setupTable (typeof (RdpGroup), p1); 167 if (p1Table [p2] == null) { 168 RdpGroup g = new RdpGroup (p1, p2); 169 g.setInternTable (this.patternPool); 170 p1Table [p2] = g; 171 } 172 return (RdpGroup) p1Table [p2]; 173 } 174 MakeInterleave(RdpPattern p1, RdpPattern p2)175 public RdpInterleave MakeInterleave (RdpPattern p1, RdpPattern p2) 176 { 177 if (p1.GetHashCode () > p2.GetHashCode ()) { 178 RdpPattern tmp = p1; 179 p1 = p2; 180 p2 = tmp; 181 } 182 183 Hashtable p1Table = setupTable (typeof (RdpInterleave), p1); 184 if (p1Table [p2] == null) { 185 RdpInterleave i = new RdpInterleave (p1, p2); 186 i.setInternTable (this.patternPool); 187 p1Table [p2] = i; 188 } 189 return (RdpInterleave) p1Table [p2]; 190 } 191 MakeAfter(RdpPattern p1, RdpPattern p2)192 public RdpAfter MakeAfter (RdpPattern p1, RdpPattern p2) 193 { 194 Hashtable p1Table = setupTable (typeof (RdpAfter), p1); 195 if (p1Table [p2] == null) { 196 RdpAfter a = new RdpAfter (p1, p2); 197 a.setInternTable (this.patternPool); 198 p1Table [p2] = a; 199 } 200 return (RdpAfter) p1Table [p2]; 201 } 202 MakeOneOrMore(RdpPattern p)203 public RdpOneOrMore MakeOneOrMore (RdpPattern p) 204 { 205 if (patternPool == null) // could be null for RdpElement etc. 206 patternPool = new Hashtable (); 207 208 Hashtable pTable = (Hashtable) patternPool [typeof (RdpOneOrMore)]; 209 if (pTable == null) { 210 pTable = new Hashtable (); 211 patternPool [typeof (RdpOneOrMore)] = pTable; 212 } 213 if (pTable [p] == null) { 214 RdpOneOrMore oom = new RdpOneOrMore (p); 215 oom.setInternTable (patternPool); 216 pTable [p] = oom; 217 } 218 return (RdpOneOrMore) pTable [p]; 219 } 220 setInternTable(Hashtable ht)221 internal void setInternTable (Hashtable ht) 222 { 223 if (this.patternPool != null) 224 return; 225 this.patternPool = ht; 226 227 Hashtable pt = ht [GetType ()] as Hashtable; 228 if (pt == null) { 229 pt = new Hashtable (); 230 ht [GetType ()] = pt; 231 } 232 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); 239 } 240 return; 241 } 242 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); 251 } 252 return; 253 } 254 255 // For rest patterns, only check recursively, without pooling. 256 RdpAttribute attr = this as RdpAttribute; 257 if (attr != null) { 258 attr.Children.setInternTable (ht); 259 return; 260 } 261 RdpElement el = this as RdpElement; 262 if (el != null) { 263 el.Children.setInternTable (ht); 264 return; 265 } 266 RdpDataExcept dex= this as RdpDataExcept; 267 if (dex != null) { 268 dex.Except.setInternTable (ht); 269 return; 270 } 271 272 switch (PatternType) { 273 case RelaxngPatternType.Empty: 274 case RelaxngPatternType.NotAllowed: 275 case RelaxngPatternType.Text: 276 case RelaxngPatternType.Data: 277 case RelaxngPatternType.Value: 278 return; 279 } 280 281 #if REPLACE_IN_ADVANCE 282 throw new InvalidOperationException (); 283 #endif 284 } 285 MarkReachableDefs()286 internal abstract void MarkReachableDefs (); 287 CheckConstraints(bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)288 internal abstract void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept); 289 290 // This method is to detect text pattern inside interleave child. ContainsText()291 internal abstract bool ContainsText (); 292 ExpandRef(Hashtable defs)293 internal virtual RdpPattern ExpandRef (Hashtable defs) 294 { 295 return this; 296 } 297 ReduceEmptyAndNotAllowed(ref bool result, Hashtable visited)298 internal virtual RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited) 299 { 300 return this; 301 } 302 303 public abstract bool Nullable { get; } 304 305 internal virtual bool IsTextValueDependent { 306 get { return false; } 307 } 308 309 internal virtual bool IsContextDependent { 310 get { return false; } 311 } 312 313 // fills QName collection GetLabels(LabelList elements, LabelList attributes)314 public void GetLabels (LabelList elements, LabelList attributes) 315 { 316 GetLabels (elements, attributes, false); 317 } 318 GetLabels(LabelList elements, LabelList attributes, bool collectNameClass)319 public abstract void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass); 320 AddNameLabel(LabelList names, RdpNameClass nc)321 internal void AddNameLabel (LabelList names, RdpNameClass nc) 322 { 323 RdpName name = nc as RdpName; 324 if (name != null) { 325 XmlQualifiedName qname = new XmlQualifiedName ( 326 name.LocalName, name.NamespaceURI); 327 names [qname] = qname; 328 return; 329 } 330 RdpNameClassChoice choice = nc as RdpNameClassChoice; 331 if (choice != null) { 332 AddNameLabel (names, choice.LValue); 333 AddNameLabel (names, choice.RValue); 334 return; 335 } 336 // For NsName and AnyName, do nothing. 337 } 338 339 #region Derivative TextDeriv(string s, XmlReader reader)340 public virtual RdpPattern TextDeriv (string s, XmlReader reader) 341 { 342 return RdpNotAllowed.Instance; 343 } 344 TextDeriv(string s, XmlReader reader, MemoizationStore memo)345 internal virtual RdpPattern TextDeriv (string s, XmlReader reader, MemoizationStore memo) 346 { 347 return TextDeriv (s, reader); 348 } 349 EmptyTextDeriv(MemoizationStore memo)350 internal virtual RdpPattern EmptyTextDeriv (MemoizationStore memo) 351 { 352 return TextDeriv (String.Empty, null, memo); 353 } 354 TextOnlyDeriv()355 internal virtual RdpPattern TextOnlyDeriv () 356 { 357 return this; 358 } 359 TextOnlyDeriv(MemoizationStore store)360 internal virtual RdpPattern TextOnlyDeriv (MemoizationStore store) 361 { 362 return this; 363 } 364 MixedTextDeriv()365 internal virtual RdpPattern MixedTextDeriv () 366 { 367 return RdpNotAllowed.Instance; 368 } 369 MixedTextDeriv(MemoizationStore memo)370 internal virtual RdpPattern MixedTextDeriv (MemoizationStore memo) 371 { 372 return RdpNotAllowed.Instance; 373 } 374 ListDeriv(string [] list, int index, XmlReader reader)375 public RdpPattern ListDeriv (string [] list, int index, XmlReader reader) 376 { 377 return listDerivInternal (list, 0, reader); 378 } 379 listDerivInternal(string [] list, int start, XmlReader reader)380 private RdpPattern listDerivInternal (string [] list, int start, XmlReader reader) 381 { 382 if (list.Length <= start) 383 return this; 384 else if (list [start].Length == 0) 385 return listDerivInternal (list, start + 1, reader); 386 else 387 return this.TextDeriv (list [start].Trim (RdpUtil.WhitespaceChars), reader).listDerivInternal (list, start + 1, reader); 388 } 389 390 // Choice(this, p) Choice(RdpPattern p)391 public virtual RdpPattern Choice (RdpPattern p) 392 { 393 if (p is RdpNotAllowed) 394 return this; 395 else if (this is RdpNotAllowed) 396 return p; 397 else 398 return MakeChoice (this, p); 399 } 400 401 // Group(this, p) Group(RdpPattern p)402 public virtual RdpPattern Group (RdpPattern p) 403 { 404 if (p is RdpNotAllowed || this is RdpNotAllowed) 405 return RdpNotAllowed.Instance; 406 else if (p is RdpEmpty) 407 return this; 408 else if (this is RdpEmpty) 409 return p; 410 else 411 return MakeGroup (this, p); 412 } 413 414 // Interleave(this, p) Interleave(RdpPattern p)415 public virtual RdpPattern Interleave (RdpPattern p) 416 { 417 if (p is RdpNotAllowed || this is RdpNotAllowed) 418 return RdpNotAllowed.Instance; 419 else if (p is RdpEmpty) 420 return this; 421 else if (this is RdpEmpty) 422 return p; 423 else 424 return MakeInterleave (this, p); 425 } 426 427 // After(this, p) After(RdpPattern p)428 public virtual RdpPattern After (RdpPattern p) 429 { 430 if (this is RdpNotAllowed || p is RdpNotAllowed) 431 return RdpNotAllowed.Instance; 432 else 433 return MakeAfter (this, p); 434 } 435 436 437 // applyAfter((f, p1=this), p2) ApplyAfter(RdpApplyAfterHandler h)438 public virtual RdpPattern ApplyAfter (RdpApplyAfterHandler h) 439 { 440 throw new Exception ("INTERNAL ERROR: should not happen. This is " + this); 441 } 442 443 // startTagOpenDeriv (this, qname) 444 // startTagOpenDeriv _ qn = NotAllowed (default) StartTagOpenDeriv(string name, string ns)445 public virtual RdpPattern StartTagOpenDeriv (string name, string ns) 446 { 447 return RdpNotAllowed.Instance; 448 } 449 StartTagOpenDeriv(string name, string ns, MemoizationStore memo)450 internal virtual RdpPattern StartTagOpenDeriv (string name, string ns, MemoizationStore memo) 451 { 452 return StartTagOpenDeriv (name, ns); 453 } 454 455 // attDeriv(ctx, this, att) 456 // attDeriv _ _ _ = NotAllowed AttDeriv(string name, string ns, string value, XmlReader reader)457 public virtual RdpPattern AttDeriv (string name, string ns, string value, XmlReader reader) 458 { 459 return RdpNotAllowed.Instance; 460 } 461 StartAttDeriv(string name, string ns)462 public virtual RdpPattern StartAttDeriv (string name, string ns) 463 { 464 return RdpNotAllowed.Instance; 465 } 466 StartAttDeriv(string name, string ns, MemoizationStore memo)467 internal virtual RdpPattern StartAttDeriv (string name, string ns, MemoizationStore memo) 468 { 469 return StartAttDeriv (name, ns); 470 } 471 EndAttDeriv()472 public virtual RdpPattern EndAttDeriv () 473 { 474 return RdpNotAllowed.Instance; 475 } 476 EndAttDeriv(MemoizationStore memo)477 internal virtual RdpPattern EndAttDeriv (MemoizationStore memo) 478 { 479 return EndAttDeriv (); 480 } 481 ValueMatch(string s, XmlReader reader)482 public bool ValueMatch (string s, XmlReader reader) 483 { 484 return Nullable && Util.IsWhitespace (s) || 485 TextDeriv (s, reader).Nullable; 486 } 487 StartTagCloseDeriv()488 public virtual RdpPattern StartTagCloseDeriv () 489 { 490 return this; 491 } 492 StartTagCloseDeriv(MemoizationStore memo)493 internal virtual RdpPattern StartTagCloseDeriv (MemoizationStore memo) 494 { 495 return StartTagCloseDeriv (); 496 } 497 OneOrMore()498 public RdpPattern OneOrMore () 499 { 500 if (PatternType == RelaxngPatternType.NotAllowed) 501 return RdpNotAllowed.Instance; 502 else 503 return MakeOneOrMore (this); 504 } 505 EndTagDeriv()506 public virtual RdpPattern EndTagDeriv () 507 { 508 return RdpNotAllowed.Instance; 509 } 510 EndTagDeriv(MemoizationStore memo)511 internal virtual RdpPattern EndTagDeriv (MemoizationStore memo) 512 { 513 return EndTagDeriv (); 514 } 515 #endregion 516 } 517 518 // Empty 519 public class RdpEmpty : RdpPattern 520 { RdpEmpty()521 public RdpEmpty () {} RdpEmpty()522 static RdpEmpty () 523 { 524 instance = new RdpEmpty (); 525 } 526 527 public override bool Nullable { 528 get { return true; } 529 } 530 531 internal override bool IsTextValueDependent { 532 get { return false; } 533 } 534 535 internal override bool IsContextDependent { 536 get { return false; } 537 } 538 539 static RdpEmpty instance; 540 public static RdpEmpty Instance { 541 get { return instance; } 542 } 543 544 public override RelaxngPatternType PatternType { 545 get { return RelaxngPatternType.Empty; } 546 } 547 548 public override RdpContentType ContentType { 549 get { return RdpContentType.Empty; } 550 } 551 GetLabels(LabelList elements, LabelList attributes, bool collectNameClass)552 public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass) 553 { 554 // do nothing 555 } 556 MarkReachableDefs()557 internal override void MarkReachableDefs () 558 { 559 // do nothing 560 } 561 CheckConstraints(bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)562 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept) 563 { 564 if (dataExcept) 565 throw new RelaxngException ("empty cannot appear under except of a data pattern."); 566 } 567 ContainsText()568 internal override bool ContainsText() 569 { 570 return false; 571 } 572 } 573 574 // NotAllowed 575 public class RdpNotAllowed : RdpPattern 576 { RdpNotAllowed()577 public RdpNotAllowed () {} RdpNotAllowed()578 static RdpNotAllowed () 579 { 580 instance = new RdpNotAllowed (); 581 } 582 583 static RdpNotAllowed instance; 584 public static RdpNotAllowed Instance { 585 get { return instance; } 586 } 587 588 public override bool Nullable { 589 get { return false; } 590 } 591 592 internal override bool IsTextValueDependent { 593 get { return false; } 594 } 595 596 internal override bool IsContextDependent { 597 get { return false; } 598 } 599 ApplyAfter(RdpApplyAfterHandler h)600 public override RdpPattern ApplyAfter (RdpApplyAfterHandler h) 601 { 602 return RdpNotAllowed.Instance; 603 } 604 605 public override RelaxngPatternType PatternType { 606 get { return RelaxngPatternType.NotAllowed; } 607 } 608 609 public override RdpContentType ContentType { 610 get { return RdpContentType.Empty; } 611 } 612 MarkReachableDefs()613 internal override void MarkReachableDefs () 614 { 615 // do nothing 616 } 617 CheckConstraints(bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)618 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept) 619 { 620 // do nothing 621 } 622 ContainsText()623 internal override bool ContainsText() 624 { 625 return false; 626 } 627 GetLabels(LabelList elements, LabelList attributes, bool collectNameClass)628 public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass) 629 { 630 // FIXME: Supposed to clear something here? 631 } 632 } 633 634 // Text 635 public class RdpText : RdpPattern 636 { 637 static RdpText instance; 638 public static RdpText Instance { 639 get { return instance; } 640 } 641 RdpText()642 public RdpText () {} RdpText()643 static RdpText () 644 { 645 instance = new RdpText (); 646 } 647 648 public override bool Nullable { 649 get { return true; } 650 } 651 652 internal override bool IsTextValueDependent { 653 get { return false; } 654 } 655 656 internal override bool IsContextDependent { 657 get { return false; } 658 } 659 660 public override RelaxngPatternType PatternType { 661 get { return RelaxngPatternType.Text; } 662 } 663 664 public override RdpContentType ContentType { 665 get { return RdpContentType.Complex; } 666 } 667 TextDeriv(string s, XmlReader reader)668 public override RdpPattern TextDeriv (string s, XmlReader reader) 669 { 670 return this; 671 } 672 EmptyTextDeriv(MemoizationStore memo)673 internal override RdpPattern EmptyTextDeriv (MemoizationStore memo) 674 { 675 return this; 676 } 677 MixedTextDeriv()678 internal override RdpPattern MixedTextDeriv () 679 { 680 return this; 681 } 682 MixedTextDeriv(MemoizationStore memo)683 internal override RdpPattern MixedTextDeriv (MemoizationStore memo) 684 { 685 return this; 686 } 687 MarkReachableDefs()688 internal override void MarkReachableDefs () 689 { 690 // do nothing 691 } 692 CheckConstraints(bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)693 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept) 694 { 695 if (list) 696 throw new RelaxngException ("text is not allowed under a list."); 697 if (dataExcept) 698 throw new RelaxngException ("text is not allowed under except of a list."); 699 } 700 ContainsText()701 internal override bool ContainsText() 702 { 703 return true; 704 } 705 GetLabels(LabelList elements, LabelList attributes, bool collectNameClass)706 public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass) 707 { 708 // do nothing 709 } 710 } 711 712 // AbstractBinary 713 public abstract class RdpAbstractBinary : RdpPattern 714 { RdpAbstractBinary(RdpPattern l, RdpPattern r)715 public RdpAbstractBinary (RdpPattern l, RdpPattern r) 716 { 717 this.l = l; 718 this.r = r; 719 } 720 721 RdpPattern l; 722 public RdpPattern LValue { 723 get { return l; } 724 set { l = value; } 725 } 726 727 RdpPattern r; 728 public RdpPattern RValue { 729 get { return r; } 730 set { r = value; } 731 } 732 733 RdpContentType computedContentType = RdpContentType.Invalid; 734 public override RdpContentType ContentType { 735 get { 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."); 743 else 744 computedContentType = RdpContentType.Complex; 745 } 746 return computedContentType; 747 } 748 } 749 750 bool expanded; ExpandRef(Hashtable defs)751 internal override RdpPattern ExpandRef (Hashtable defs) 752 { 753 if (!expanded) { 754 l = l.ExpandRef (defs); 755 r = r.ExpandRef (defs); 756 } 757 return this; 758 } 759 ReduceEmptyAndNotAllowed(ref bool result, Hashtable visited)760 internal override RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited) 761 { 762 if (visited.Contains (this)) 763 return this; 764 visited.Add (this, this); 765 766 if (LValue.PatternType == RelaxngPatternType.NotAllowed || 767 RValue.PatternType == RelaxngPatternType.NotAllowed) { 768 result = true; 769 return RdpNotAllowed.Instance; 770 } else if (LValue.PatternType == RelaxngPatternType.Empty) { 771 result = true; 772 return RValue.ReduceEmptyAndNotAllowed (ref result, visited); 773 } else if (RValue.PatternType == RelaxngPatternType.Empty) { 774 result = true; 775 return LValue.ReduceEmptyAndNotAllowed (ref result, visited); 776 } else { 777 LValue = LValue.ReduceEmptyAndNotAllowed (ref result, visited); 778 RValue = RValue.ReduceEmptyAndNotAllowed (ref result, visited); 779 return this; 780 } 781 } 782 MarkReachableDefs()783 internal override void MarkReachableDefs () 784 { 785 l.MarkReachableDefs (); 786 r.MarkReachableDefs (); 787 } 788 ContainsText()789 internal override bool ContainsText() 790 { 791 return l.ContainsText () || r.ContainsText (); 792 } 793 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. CheckNameOverlap(bool checkElements)798 internal void CheckNameOverlap (bool checkElements) 799 { 800 if (RdpUtil.NamesOverlap (LValue, RValue, checkElements)) 801 throw new RelaxngException ("Duplicate attributes inside a group or an interleave is not allowed."); 802 return; 803 } 804 } 805 806 // Choice 807 public class RdpChoice : RdpAbstractBinary 808 { RdpChoice(RdpPattern l, RdpPattern r)809 public RdpChoice (RdpPattern l, RdpPattern r) : base (l, r) 810 { 811 } 812 813 public override bool Nullable { 814 get { 815 if (!nullableComputed) { 816 isNullable = 817 LValue.Nullable || RValue.Nullable; 818 nullableComputed = true; 819 } 820 return isNullable; 821 } 822 } 823 824 bool isTextValueDependentComputed; 825 bool isTextValueDependent; 826 827 internal override bool IsTextValueDependent { 828 get { 829 if (!isTextValueDependentComputed) { 830 isTextValueDependent = LValue.IsTextValueDependent || RValue.IsTextValueDependent; 831 isTextValueDependentComputed = true; 832 } 833 return isTextValueDependent; 834 } 835 } 836 837 bool isContextDependentComputed; 838 bool isContextDependent; 839 840 internal override bool IsContextDependent { 841 get { 842 if (!isContextDependentComputed) { 843 isContextDependent = LValue.IsContextDependent || RValue.IsContextDependent; 844 isContextDependentComputed = true; 845 } 846 return isContextDependent; 847 } 848 } 849 850 public override RelaxngPatternType PatternType { 851 get { return RelaxngPatternType.Choice; } 852 } 853 854 RdpContentType computedContentType = RdpContentType.Invalid; 855 public override RdpContentType ContentType { 856 get { 857 if (computedContentType == RdpContentType.Invalid) { 858 if (LValue.ContentType == RdpContentType.Simple || 859 RValue.ContentType == RdpContentType.Simple) 860 computedContentType = RdpContentType.Simple; 861 else 862 computedContentType = base.ContentType; 863 } 864 return computedContentType; 865 } 866 } 867 GetLabels(LabelList elements, LabelList attributes, bool collectNameClass)868 public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass) 869 { 870 LValue.GetLabels (elements, attributes, collectNameClass); 871 RValue.GetLabels (elements, attributes, collectNameClass); 872 } 873 874 ReduceEmptyAndNotAllowed(ref bool result, Hashtable visited)875 internal override RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited) 876 { 877 if (visited.Contains (this)) 878 return this; 879 visited.Add (this, this); 880 881 if (LValue.PatternType == RelaxngPatternType.NotAllowed && 882 RValue.PatternType == RelaxngPatternType.NotAllowed) { 883 result = true; 884 return RdpNotAllowed.Instance; 885 } else if (LValue.PatternType == RelaxngPatternType.NotAllowed) { 886 result = true; 887 return RValue.ReduceEmptyAndNotAllowed (ref result, visited); 888 } else if (RValue.PatternType == RelaxngPatternType.NotAllowed) { 889 result = true; 890 return LValue.ReduceEmptyAndNotAllowed (ref result, visited); 891 } else if (LValue.PatternType == RelaxngPatternType.Empty && 892 RValue.PatternType == RelaxngPatternType.Empty) { 893 result = true; 894 return RdpEmpty.Instance; 895 } else if (RValue.PatternType == RelaxngPatternType.Empty) { 896 result = true; 897 RValue = LValue.ReduceEmptyAndNotAllowed (ref result, visited); 898 LValue = RdpEmpty.Instance; 899 return this; 900 } else { 901 LValue = LValue.ReduceEmptyAndNotAllowed (ref result, visited); 902 RValue = RValue.ReduceEmptyAndNotAllowed (ref result, visited); 903 return this; 904 } 905 } 906 TextDeriv(string s, XmlReader reader)907 public override RdpPattern TextDeriv (string s, XmlReader reader) 908 { 909 return LValue.TextDeriv (s, reader).Choice (RValue.TextDeriv (s, reader)); 910 } 911 TextDeriv(string s, XmlReader reader, MemoizationStore memo)912 internal override RdpPattern TextDeriv (string s, XmlReader reader, MemoizationStore memo) 913 { 914 return memo.TextDeriv (LValue, s, reader).Choice (memo.TextDeriv (RValue, s, reader)); 915 } 916 EmptyTextDeriv(MemoizationStore memo)917 internal override RdpPattern EmptyTextDeriv (MemoizationStore memo) 918 { 919 return memo.EmptyTextDeriv (LValue) 920 .Choice (memo.EmptyTextDeriv (RValue)); 921 } 922 TextOnlyDeriv()923 internal override RdpPattern TextOnlyDeriv () 924 { 925 return LValue.TextOnlyDeriv ().Choice ( 926 RValue.TextOnlyDeriv ()); 927 } 928 TextOnlyDeriv(MemoizationStore memo)929 internal override RdpPattern TextOnlyDeriv (MemoizationStore memo) 930 { 931 return memo.TextOnlyDeriv (LValue).Choice ( 932 memo.TextOnlyDeriv (RValue)); 933 } 934 MixedTextDeriv()935 internal override RdpPattern MixedTextDeriv () 936 { 937 return LValue.MixedTextDeriv ().Choice ( 938 RValue.MixedTextDeriv ()); 939 } 940 MixedTextDeriv(MemoizationStore memo)941 internal override RdpPattern MixedTextDeriv (MemoizationStore memo) 942 { 943 return memo.MixedTextDeriv (LValue).Choice ( 944 memo.MixedTextDeriv (RValue)); 945 } 946 ApplyAfter(RdpApplyAfterHandler handler)947 public override RdpPattern ApplyAfter (RdpApplyAfterHandler handler) 948 { 949 // return handler (LValue).Choice (handler (RValue)); 950 return LValue.ApplyAfter (handler).Choice (RValue.ApplyAfter (handler)); 951 } 952 StartTagOpenDeriv(string name, string ns)953 public override RdpPattern StartTagOpenDeriv (string name, string ns) 954 { 955 #if UseStatic 956 return RdpUtil.Choice ( 957 RdpUtil.StartTagOpenDeriv (LValue, qname), 958 RdpUtil.StartTagOpenDeriv (RValue, qname)); 959 #else 960 RdpPattern lDeriv = LValue.StartTagOpenDeriv (name, ns); 961 return lDeriv.Choice (RValue.StartTagOpenDeriv (name, ns)); 962 #endif 963 } 964 StartTagOpenDeriv(string name, string ns, MemoizationStore memo)965 internal override RdpPattern StartTagOpenDeriv (string name, string ns, MemoizationStore memo) 966 { 967 RdpPattern lDeriv = memo.StartTagOpenDeriv (LValue, name, ns); 968 return lDeriv.Choice (memo.StartTagOpenDeriv (RValue, name, ns)); 969 } 970 971 // attDeriv cx (Choice p1 p2) att = 972 // choice (attDeriv cx p1 att) (attDeriv cx p2 att) AttDeriv(string name, string ns, string value, XmlReader reader)973 public override RdpPattern AttDeriv (string name, string ns, string value, XmlReader reader) 974 { 975 return LValue.AttDeriv (name, ns, value, reader) 976 .Choice (RValue.AttDeriv (name, ns, value, reader)); 977 } 978 StartAttDeriv(string name, string ns)979 public override RdpPattern StartAttDeriv (string name, string ns) 980 { 981 RdpPattern lDeriv = LValue.StartAttDeriv (name, ns); 982 return lDeriv.Choice (RValue.StartAttDeriv (name, ns)); 983 } 984 StartAttDeriv(string name, string ns, MemoizationStore memo)985 internal override RdpPattern StartAttDeriv (string name, string ns, MemoizationStore memo) 986 { 987 return memo.StartAttDeriv (LValue, name, ns) 988 .Choice (memo.StartAttDeriv (RValue, name, ns)); 989 } 990 EndAttDeriv()991 public override RdpPattern EndAttDeriv () 992 { 993 return LValue.EndAttDeriv ().Choice (RValue.EndAttDeriv ()); 994 } 995 EndAttDeriv(MemoizationStore memo)996 internal override RdpPattern EndAttDeriv (MemoizationStore memo) 997 { 998 return memo.EndAttDeriv (LValue).Choice (memo.EndAttDeriv (RValue)); 999 } 1000 1001 // startTagCloseDeriv (Choice p1 p2) = 1002 // choice (startTagCloseDeriv p1) (startTagCloseDeriv p2) StartTagCloseDeriv()1003 public override RdpPattern StartTagCloseDeriv () 1004 { 1005 return LValue.StartTagCloseDeriv () 1006 .Choice (RValue.StartTagCloseDeriv ()); 1007 } 1008 StartTagCloseDeriv(MemoizationStore memo)1009 internal override RdpPattern StartTagCloseDeriv (MemoizationStore memo) 1010 { 1011 return memo.StartTagCloseDeriv (LValue) 1012 .Choice (memo.StartTagCloseDeriv (RValue)); 1013 } 1014 EndTagDeriv()1015 public override RdpPattern EndTagDeriv () 1016 { 1017 return LValue.EndTagDeriv ().Choice (RValue.EndTagDeriv ()); 1018 } 1019 EndTagDeriv(MemoizationStore memo)1020 internal override RdpPattern EndTagDeriv (MemoizationStore memo) 1021 { 1022 return memo.EndTagDeriv (LValue).Choice (memo.EndTagDeriv (RValue)); 1023 } 1024 CheckConstraints(bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)1025 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept) 1026 { 1027 LValue.CheckConstraints (attribute, oneOrMore, oneOrMoreGroup, oneOrMoreInterleave, list, dataExcept); 1028 RValue.CheckConstraints (attribute, oneOrMore, oneOrMoreGroup, oneOrMoreInterleave, list, dataExcept); 1029 } 1030 } 1031 1032 // Interleave 1033 public class RdpInterleave : RdpAbstractBinary 1034 { RdpInterleave(RdpPattern l, RdpPattern r)1035 public RdpInterleave (RdpPattern l, RdpPattern r) : base (l, r) 1036 { 1037 } 1038 1039 public override bool Nullable { 1040 get { 1041 if (!nullableComputed) { 1042 isNullable = 1043 LValue.Nullable && RValue.Nullable; 1044 nullableComputed = true; 1045 } 1046 return isNullable; 1047 } 1048 } 1049 1050 internal override bool IsTextValueDependent { 1051 get { return LValue.IsTextValueDependent || RValue.IsTextValueDependent; } 1052 } 1053 1054 internal override bool IsContextDependent { 1055 get { return LValue.IsContextDependent || RValue.IsContextDependent; } 1056 } 1057 GetLabels(LabelList elements, LabelList attributes, bool collectNameClass)1058 public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass) 1059 { 1060 LValue.GetLabels (elements, attributes, collectNameClass); 1061 RValue.GetLabels (elements, attributes, collectNameClass); 1062 } 1063 ReduceEmptyAndNotAllowed(ref bool result, Hashtable visited)1064 internal override RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited) 1065 { 1066 if (visited.Contains (this)) 1067 return this; 1068 visited.Add (this, this); 1069 1070 if (LValue.PatternType == RelaxngPatternType.NotAllowed || 1071 RValue.PatternType == RelaxngPatternType.NotAllowed) { 1072 result = true; 1073 return RdpNotAllowed.Instance; 1074 } else { 1075 LValue = LValue.ReduceEmptyAndNotAllowed (ref result, visited); 1076 RValue = RValue.ReduceEmptyAndNotAllowed (ref result, visited); 1077 return this; 1078 } 1079 } 1080 TextDeriv(string s, XmlReader reader)1081 public override RdpPattern TextDeriv (string s, XmlReader reader) 1082 { 1083 return LValue.TextDeriv (s, reader).Interleave (RValue) 1084 .Choice (LValue.Interleave (RValue.TextDeriv (s, reader))); 1085 } 1086 TextDeriv(string s, XmlReader reader, MemoizationStore memo)1087 internal override RdpPattern TextDeriv (string s, XmlReader reader, MemoizationStore memo) 1088 { 1089 return memo.TextDeriv (LValue, s, reader).Interleave (RValue) 1090 .Choice (LValue.Interleave (memo.TextDeriv (RValue, s, reader))); 1091 } 1092 EmptyTextDeriv(MemoizationStore memo)1093 internal override RdpPattern EmptyTextDeriv (MemoizationStore memo) 1094 { 1095 return memo.EmptyTextDeriv (LValue).Interleave (RValue) 1096 .Choice (LValue.Interleave (memo.EmptyTextDeriv (RValue))); 1097 } 1098 TextOnlyDeriv()1099 internal override RdpPattern TextOnlyDeriv () 1100 { 1101 return LValue.TextOnlyDeriv ().Interleave ( 1102 RValue.TextOnlyDeriv ()); 1103 } 1104 TextOnlyDeriv(MemoizationStore memo)1105 internal override RdpPattern TextOnlyDeriv (MemoizationStore memo) 1106 { 1107 return memo.TextOnlyDeriv (LValue).Interleave ( 1108 memo.TextOnlyDeriv (RValue)); 1109 } 1110 MixedTextDeriv()1111 internal override RdpPattern MixedTextDeriv () 1112 { 1113 return LValue.MixedTextDeriv ().Interleave (RValue).Choice ( 1114 LValue.Interleave (RValue.MixedTextDeriv ())); 1115 } 1116 MixedTextDeriv(MemoizationStore memo)1117 internal override RdpPattern MixedTextDeriv (MemoizationStore memo) 1118 { 1119 return memo.MixedTextDeriv (LValue).Interleave (RValue).Choice ( 1120 LValue.Interleave (memo.MixedTextDeriv (RValue))); 1121 } 1122 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) ) StartTagOpenDeriv(string name, string ns)1125 public override RdpPattern StartTagOpenDeriv (string name, string ns) 1126 { 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); 1133 } 1134 StartTagOpenDeriv(string name, string ns, MemoizationStore memo)1135 internal override RdpPattern StartTagOpenDeriv (string name, string ns, MemoizationStore memo) 1136 { 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); 1143 } 1144 1145 // attDeriv cx (Interleave p1 p2) att = 1146 // choice (interleave (attDeriv cx p1 att) p2) 1147 // (interleave p1 (attDeriv cx p2 att)) AttDeriv(string name, string ns, string value, XmlReader reader)1148 public override RdpPattern AttDeriv (string name, string ns, string value, XmlReader reader) 1149 { 1150 return LValue.AttDeriv (name, ns, value, reader) 1151 .Interleave (RValue) 1152 .Choice (LValue.Interleave ( 1153 RValue.AttDeriv (name, ns, value, reader))); 1154 } 1155 StartAttDeriv(string name, string ns)1156 public override RdpPattern StartAttDeriv (string name, string ns) 1157 { 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); 1164 } 1165 StartAttDeriv(string name, string ns, MemoizationStore memo)1166 internal override RdpPattern StartAttDeriv (string name, string ns, MemoizationStore memo) 1167 { 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); 1174 } 1175 1176 // startTagCloseDeriv (Interleave p1 p2) = 1177 // interleave (startTagCloseDeriv p1) (startTagCloseDeriv p2) StartTagCloseDeriv()1178 public override RdpPattern StartTagCloseDeriv () 1179 { 1180 return LValue.StartTagCloseDeriv () 1181 .Interleave (RValue.StartTagCloseDeriv ()); 1182 } 1183 StartTagCloseDeriv(MemoizationStore memo)1184 internal override RdpPattern StartTagCloseDeriv (MemoizationStore memo) 1185 { 1186 return memo.StartTagCloseDeriv (LValue) 1187 .Interleave (memo.StartTagCloseDeriv (RValue)); 1188 } 1189 1190 public override RelaxngPatternType PatternType { 1191 get { return RelaxngPatternType.Interleave; } 1192 } 1193 CheckConstraints(bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)1194 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept) 1195 { 1196 if (list) 1197 throw new RelaxngException ("interleave is not allowed under a list."); 1198 if (dataExcept) 1199 throw new RelaxngException ("interleave is not allowed under except of a data."); 1200 1201 // 7.1 1202 LValue.CheckConstraints (attribute, oneOrMore, oneOrMoreGroup, oneOrMore, list, dataExcept); 1203 RValue.CheckConstraints (attribute, oneOrMore, oneOrMoreGroup, oneOrMore, list, dataExcept); 1204 1205 // unique name analysis - 7.3 and part of 7.4 1206 CheckNameOverlap (true); 1207 1208 // (2) text/text prohibited 1209 if (LValue.ContainsText () && RValue.ContainsText ()) 1210 throw new RelaxngException ("Both branches of the interleave contains a text pattern."); 1211 } 1212 } 1213 1214 // Group 1215 public class RdpGroup : RdpAbstractBinary 1216 { RdpGroup(RdpPattern l, RdpPattern r)1217 public RdpGroup (RdpPattern l, RdpPattern r) : base (l, r) 1218 { 1219 } 1220 1221 public override bool Nullable { 1222 get { 1223 if (!nullableComputed) { 1224 isNullable = 1225 LValue.Nullable && RValue.Nullable; 1226 nullableComputed = true; 1227 } 1228 return isNullable; 1229 } 1230 } 1231 1232 internal override bool IsTextValueDependent { 1233 get { return LValue.IsTextValueDependent || (LValue.Nullable ? RValue.IsTextValueDependent : false); } 1234 } 1235 1236 internal override bool IsContextDependent { 1237 get { return LValue.IsContextDependent || (LValue.Nullable ? RValue.IsContextDependent : false); } 1238 } 1239 GetLabels(LabelList elements, LabelList attributes, bool collectNameClass)1240 public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass) 1241 { 1242 LValue.GetLabels (elements, attributes, collectNameClass); 1243 if (LValue.Nullable) 1244 RValue.GetLabels (elements, attributes, collectNameClass); 1245 else 1246 RValue.GetLabels (null, attributes, collectNameClass); 1247 } 1248 TextDeriv(string s, XmlReader reader)1249 public override RdpPattern TextDeriv (string s, XmlReader reader) 1250 { 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; 1256 } 1257 TextDeriv(string s, XmlReader reader, MemoizationStore memo)1258 internal override RdpPattern TextDeriv (string s, XmlReader reader, MemoizationStore memo) 1259 { 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; 1265 } 1266 EmptyTextDeriv(MemoizationStore memo)1267 internal override RdpPattern EmptyTextDeriv (MemoizationStore memo) 1268 { 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; 1274 } 1275 TextOnlyDeriv()1276 internal override RdpPattern TextOnlyDeriv () 1277 { 1278 RdpPattern p = LValue.TextOnlyDeriv (); 1279 return p.PatternType == RelaxngPatternType.NotAllowed ? 1280 p : p.Group (RValue.TextOnlyDeriv ()); 1281 } 1282 TextOnlyDeriv(MemoizationStore memo)1283 internal override RdpPattern TextOnlyDeriv (MemoizationStore memo) 1284 { 1285 RdpPattern p = memo.TextOnlyDeriv (LValue); 1286 return p.PatternType == RelaxngPatternType.NotAllowed ? 1287 p : p.Group (memo.TextOnlyDeriv (RValue)); 1288 } 1289 MixedTextDeriv()1290 internal override RdpPattern MixedTextDeriv () 1291 { 1292 RdpPattern p = LValue.MixedTextDeriv ().Group (RValue); 1293 return LValue.Nullable ? 1294 p.Choice (RValue.MixedTextDeriv ()) : p; 1295 } 1296 MixedTextDeriv(MemoizationStore memo)1297 internal override RdpPattern MixedTextDeriv (MemoizationStore memo) 1298 { 1299 RdpPattern p = memo.MixedTextDeriv (LValue).Group (RValue); 1300 return LValue.Nullable ? 1301 p.Choice (memo.MixedTextDeriv (RValue)) : p; 1302 } 1303 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) 1308 // else 1309 // x StartTagOpenDeriv(string name, string ns)1310 public override RdpPattern StartTagOpenDeriv (string name, string ns) 1311 { 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)); 1317 else 1318 return x; 1319 } 1320 StartTagOpenDeriv(string name, string ns, MemoizationStore memo)1321 internal override RdpPattern StartTagOpenDeriv (string name, string ns, MemoizationStore memo) 1322 { 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)); 1328 else 1329 return x; 1330 } 1331 1332 // attDeriv cx (Group p1 p2) att = 1333 // choice (group (attDeriv cx p1 att) p2) 1334 // (group p1 (attDeriv cx p2 att)) AttDeriv(string name, string ns, string value, XmlReader reader)1335 public override RdpPattern AttDeriv (string name, string ns, string value, XmlReader reader) 1336 { 1337 return LValue.AttDeriv (name, ns, value, reader).Group (RValue) 1338 .Choice (LValue.Group ( 1339 RValue.AttDeriv (name, ns, value, reader))); 1340 } 1341 1342 // startAttDeriv (group p1 p2) == startAttDeriv (interleave p1 p2) StartAttDeriv(string name, string ns)1343 public override RdpPattern StartAttDeriv (string name, string ns) 1344 { 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); 1351 } 1352 StartAttDeriv(string name, string ns, MemoizationStore memo)1353 internal override RdpPattern StartAttDeriv (string name, string ns, MemoizationStore memo) 1354 { 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); 1361 } 1362 1363 // startTagCloseDeriv (Group p1 p2) = 1364 // group (startTagCloseDeriv p1) (startTagCloseDeriv p2) StartTagCloseDeriv()1365 public override RdpPattern StartTagCloseDeriv () 1366 { 1367 RdpPattern p = LValue.StartTagCloseDeriv (); 1368 return p.PatternType == RelaxngPatternType.NotAllowed ? 1369 p : p.Group (RValue.StartTagCloseDeriv ()); 1370 } 1371 StartTagCloseDeriv(MemoizationStore memo)1372 internal override RdpPattern StartTagCloseDeriv (MemoizationStore memo) 1373 { 1374 RdpPattern p = memo.StartTagCloseDeriv (LValue); 1375 return p.PatternType == RelaxngPatternType.NotAllowed ? 1376 p : p.Group (memo.StartTagCloseDeriv (RValue)); 1377 } 1378 1379 public override RelaxngPatternType PatternType { 1380 get { return RelaxngPatternType.Group; } 1381 } 1382 CheckConstraints(bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)1383 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept) 1384 { 1385 if (dataExcept) 1386 throw new RelaxngException ("interleave is not allowed under except of a data."); 1387 1388 LValue.CheckConstraints (attribute, oneOrMore, oneOrMore, oneOrMoreInterleave, list, dataExcept); 1389 RValue.CheckConstraints (attribute, oneOrMore, oneOrMore, oneOrMoreInterleave, list, dataExcept); 1390 1391 // 7.3 1392 CheckNameOverlap (false); 1393 } 1394 } 1395 1396 public abstract class RdpAbstractSingleContent : RdpPattern 1397 { 1398 RdpPattern child; 1399 bool isExpanded; 1400 ExpandRef(Hashtable defs)1401 internal override RdpPattern ExpandRef (Hashtable defs) 1402 { 1403 if (!isExpanded) 1404 child = child.ExpandRef (defs); 1405 return this; 1406 } 1407 RdpAbstractSingleContent(RdpPattern p)1408 public RdpAbstractSingleContent (RdpPattern p) 1409 { 1410 this.child = p; 1411 } 1412 1413 public RdpPattern Child { 1414 get { return child; } 1415 set { child = value; } 1416 } 1417 MarkReachableDefs()1418 internal override void MarkReachableDefs () 1419 { 1420 child.MarkReachableDefs (); 1421 } 1422 ContainsText()1423 internal override bool ContainsText() 1424 { 1425 return child.ContainsText (); 1426 } 1427 } 1428 1429 // OneOrMore 1430 public class RdpOneOrMore : RdpAbstractSingleContent 1431 { RdpOneOrMore(RdpPattern p)1432 public RdpOneOrMore (RdpPattern p) : base (p) 1433 { 1434 } 1435 1436 public override RelaxngPatternType PatternType { 1437 get { return RelaxngPatternType.OneOrMore; } 1438 } 1439 1440 public override RdpContentType ContentType { 1441 get { 1442 if (Child.ContentType == RdpContentType.Simple) 1443 throw new RelaxngException ("Invalid content type was found."); 1444 return Child.ContentType; 1445 } 1446 } 1447 1448 public override bool Nullable { 1449 get { return Child.Nullable; } 1450 } 1451 1452 internal override bool IsTextValueDependent { 1453 get { return Child.IsTextValueDependent; } 1454 } 1455 1456 internal override bool IsContextDependent { 1457 get { return Child.IsContextDependent; } 1458 } 1459 GetLabels(LabelList elements, LabelList attributes, bool collectNameClass)1460 public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass) 1461 { 1462 Child.GetLabels (elements, attributes, collectNameClass); 1463 } 1464 ReduceEmptyAndNotAllowed(ref bool result, Hashtable visited)1465 internal override RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited) 1466 { 1467 if (visited.Contains (this)) 1468 return this; 1469 visited.Add (this, this); 1470 1471 if (Child.PatternType == RelaxngPatternType.NotAllowed) { 1472 result = true; 1473 return RdpNotAllowed.Instance; 1474 } else if (Child.PatternType == RelaxngPatternType.Empty) 1475 return RdpEmpty.Instance; 1476 else { 1477 Child = Child.ReduceEmptyAndNotAllowed (ref result, visited); 1478 return this; 1479 } 1480 } 1481 TextDeriv(string s, XmlReader reader)1482 public override RdpPattern TextDeriv (string s, XmlReader reader) 1483 { 1484 RdpPattern p = Child.TextDeriv (s, reader); 1485 return p.PatternType == RelaxngPatternType.NotAllowed ? 1486 p : p.Group (this.Choice (RdpEmpty.Instance)); 1487 } 1488 TextDeriv(string s, XmlReader reader, MemoizationStore memo)1489 internal override RdpPattern TextDeriv (string s, XmlReader reader, MemoizationStore memo) 1490 { 1491 RdpPattern p = memo.TextDeriv (Child, s, reader); 1492 return p.PatternType == RelaxngPatternType.NotAllowed ? 1493 p : p.Group (this.Choice (RdpEmpty.Instance)); 1494 } 1495 EmptyTextDeriv(MemoizationStore memo)1496 internal override RdpPattern EmptyTextDeriv (MemoizationStore memo) 1497 { 1498 RdpPattern p = memo.EmptyTextDeriv (Child); 1499 return p.PatternType == RelaxngPatternType.NotAllowed ? 1500 p : p.Group (this.Choice (RdpEmpty.Instance)); 1501 } 1502 TextOnlyDeriv()1503 internal override RdpPattern TextOnlyDeriv () 1504 { 1505 return Child.TextOnlyDeriv ().OneOrMore (); 1506 } 1507 TextOnlyDeriv(MemoizationStore memo)1508 internal override RdpPattern TextOnlyDeriv (MemoizationStore memo) 1509 { 1510 return memo.TextOnlyDeriv (Child).OneOrMore (); 1511 } 1512 MixedTextDeriv()1513 internal override RdpPattern MixedTextDeriv () 1514 { 1515 RdpPattern p = Child.MixedTextDeriv (); 1516 return p.PatternType == RelaxngPatternType.NotAllowed ? 1517 p : p.Group (this.Choice (RdpEmpty.Instance)); 1518 } 1519 MixedTextDeriv(MemoizationStore memo)1520 internal override RdpPattern MixedTextDeriv (MemoizationStore memo) 1521 { 1522 RdpPattern p = memo.MixedTextDeriv (Child); 1523 return p.PatternType == RelaxngPatternType.NotAllowed ? 1524 p : p.Group (this.Choice (RdpEmpty.Instance)); 1525 } 1526 1527 // attDeriv cx (OneOrMore p) att = 1528 // group (attDeriv cx p att) (choice (OneOrMore p) Empty) AttDeriv(string name, string ns, string value, XmlReader reader)1529 public override RdpPattern AttDeriv (string name, string ns, string value, XmlReader reader) 1530 { 1531 RdpPattern p = Child.AttDeriv (name, ns, value, reader); 1532 return p.PatternType == RelaxngPatternType.NotAllowed ? 1533 p : p.Group (Choice (RdpEmpty.Instance)); 1534 } 1535 1536 // startTagOpenDeriv (OneOrMore p) qn = 1537 // applyAfter (flip group (choice (OneOrMore p) Empty)) 1538 // (startTagOpenDeriv p qn) StartTagOpenDeriv(string name, string ns)1539 public override RdpPattern StartTagOpenDeriv (string name, string ns) 1540 { 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)); 1545 } 1546 StartTagOpenDeriv(string name, string ns, MemoizationStore memo)1547 internal override RdpPattern StartTagOpenDeriv (string name, string ns, MemoizationStore memo) 1548 { 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)); 1553 } 1554 StartAttDeriv(string name, string ns)1555 public override RdpPattern StartAttDeriv (string name, string ns) 1556 { 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)); 1561 } 1562 StartAttDeriv(string name, string ns, MemoizationStore memo)1563 internal override RdpPattern StartAttDeriv (string name, string ns, MemoizationStore memo) 1564 { 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)); 1569 } 1570 1571 // startTagCloseDeriv (OneOrMore p) = 1572 // oneOrMore (startTagCloseDeriv p) StartTagCloseDeriv()1573 public override RdpPattern StartTagCloseDeriv () 1574 { 1575 #if UseStatic 1576 return RdpUtil.OneOrMore ( 1577 RdpUtil.StartTagCloseDeriv (children)); 1578 #else 1579 return Child.StartTagCloseDeriv ().OneOrMore (); 1580 #endif 1581 } 1582 StartTagCloseDeriv(MemoizationStore memo)1583 internal override RdpPattern StartTagCloseDeriv (MemoizationStore memo) 1584 { 1585 return memo.StartTagCloseDeriv (Child).OneOrMore (); 1586 } 1587 CheckConstraints(bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)1588 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept) 1589 { 1590 if (dataExcept) 1591 throw new RelaxngException ("oneOrMore is not allowed under except of a data."); 1592 this.Child.CheckConstraints (attribute, true, oneOrMoreGroup, oneOrMoreInterleave, list, dataExcept); 1593 } 1594 } 1595 1596 // List 1597 public class RdpList : RdpAbstractSingleContent 1598 { RdpList(RdpPattern p)1599 public RdpList (RdpPattern p) : base (p) 1600 { 1601 } 1602 ReduceEmptyAndNotAllowed(ref bool result, Hashtable visited)1603 internal override RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited) 1604 { 1605 if (visited.Contains (this)) 1606 return this; 1607 visited.Add (this, this); 1608 1609 if (Child.PatternType == RelaxngPatternType.NotAllowed) { 1610 result = true; 1611 return RdpNotAllowed.Instance; 1612 } else { 1613 Child = Child.ReduceEmptyAndNotAllowed (ref result, visited); 1614 return this; 1615 } 1616 } 1617 1618 public override bool Nullable { 1619 get { return false; } 1620 } 1621 1622 internal override bool IsTextValueDependent { 1623 get { return true; } 1624 } 1625 1626 internal override bool IsContextDependent { 1627 get { return Child.IsContextDependent; } 1628 } 1629 1630 public override RelaxngPatternType PatternType { 1631 get { return RelaxngPatternType.List; } 1632 } 1633 1634 public override RdpContentType ContentType { 1635 get { return RdpContentType.Simple; } 1636 } 1637 GetLabels(LabelList elements, LabelList attributes, bool collectNameClass)1638 public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass) 1639 { 1640 Child.GetLabels (elements, attributes, collectNameClass); 1641 } 1642 TextDeriv(string s, XmlReader reader)1643 public override RdpPattern TextDeriv (string s, XmlReader reader) 1644 { 1645 s = Util.NormalizeWhitespace (s); 1646 1647 RdpPattern p = Child.ListDeriv (s.Split (RdpUtil.WhitespaceChars), 0, reader); 1648 if (p.Nullable) 1649 return RdpEmpty.Instance; 1650 else 1651 return RdpNotAllowed.Instance; 1652 } 1653 CheckConstraints(bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)1654 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept) 1655 { 1656 if (list) 1657 throw new RelaxngException ("list is not allowed uner another list."); 1658 if (dataExcept) 1659 throw new RelaxngException ("list is not allowed under except of a data."); 1660 this.Child.CheckConstraints (attribute, oneOrMore, oneOrMoreGroup, oneOrMoreInterleave, true, dataExcept); 1661 } 1662 } 1663 1664 // Data 1665 public class RdpData : RdpPattern 1666 { RdpData(RdpDatatype dt)1667 public RdpData (RdpDatatype dt) 1668 { 1669 this.dt = dt; 1670 } 1671 1672 RdpDatatype dt; 1673 public RdpDatatype Datatype { 1674 get { return dt; } 1675 } 1676 1677 public override bool Nullable { 1678 get { return false; } 1679 } 1680 1681 internal override bool IsTextValueDependent { 1682 get { return true; } 1683 } 1684 1685 internal override bool IsContextDependent { 1686 get { return dt.IsContextDependent; } 1687 } 1688 1689 public override RelaxngPatternType PatternType { 1690 get { return RelaxngPatternType.Data; } 1691 } 1692 1693 public override RdpContentType ContentType { 1694 get { return RdpContentType.Simple; } 1695 } 1696 GetLabels(LabelList elements, LabelList attributes, bool collectNameClass)1697 public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass) 1698 { 1699 // do nothing. 1700 } 1701 TextDeriv(string s, XmlReader reader)1702 public override RdpPattern TextDeriv (string s, XmlReader reader) 1703 { 1704 if (dt.IsAllowed (s, reader)) 1705 return RdpEmpty.Instance; 1706 else 1707 return RdpNotAllowed.Instance; 1708 } 1709 MarkReachableDefs()1710 internal override void MarkReachableDefs () 1711 { 1712 // do nothing 1713 } 1714 CheckConstraints(bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)1715 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept) 1716 { 1717 // do nothing 1718 } 1719 ContainsText()1720 internal override bool ContainsText() 1721 { 1722 return false; 1723 } 1724 } 1725 1726 // DataExcept 1727 public class RdpDataExcept : RdpData 1728 { RdpDataExcept(RdpDatatype dt, RdpPattern except)1729 public RdpDataExcept (RdpDatatype dt, RdpPattern except) 1730 : base (dt) 1731 { 1732 this.except = except; 1733 } 1734 1735 RdpPattern except; 1736 public RdpPattern Except { 1737 get { return except; } 1738 set { except = value; } 1739 } 1740 1741 public override RelaxngPatternType PatternType { 1742 get { return RelaxngPatternType.DataExcept; } 1743 } 1744 1745 public override RdpContentType ContentType { 1746 get { 1747 RdpContentType c = except.ContentType; // conformance required for except pattern. 1748 return RdpContentType.Simple; 1749 } 1750 } 1751 ReduceEmptyAndNotAllowed(ref bool result, Hashtable visited)1752 internal override RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited) 1753 { 1754 if (visited.Contains (this)) 1755 return this; 1756 visited.Add (this, this); 1757 1758 if (except.PatternType == RelaxngPatternType.NotAllowed) { 1759 result = true; 1760 return new RdpData (this.Datatype); 1761 } else { 1762 except = except.ReduceEmptyAndNotAllowed (ref result, visited); 1763 return this; 1764 } 1765 } 1766 TextDeriv(string s, XmlReader reader)1767 public override RdpPattern TextDeriv (string s, XmlReader reader) 1768 { 1769 if (Datatype.IsAllowed (s, reader) && !except.TextDeriv (s, reader).Nullable) 1770 return RdpEmpty.Instance; 1771 else 1772 return RdpNotAllowed.Instance; 1773 } 1774 CheckConstraints(bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)1775 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept) 1776 { 1777 this.except.CheckConstraints (attribute, oneOrMore, oneOrMoreGroup, oneOrMoreInterleave, list, true); 1778 } 1779 ContainsText()1780 internal override bool ContainsText() 1781 { 1782 return except.ContainsText (); 1783 } 1784 } 1785 1786 // Value 1787 public class RdpValue : RdpPattern 1788 { RdpValue(RdpDatatype dt, string value)1789 public RdpValue (RdpDatatype dt, string value) 1790 { 1791 this.dt = dt; 1792 this.value = value; 1793 } 1794 1795 RdpDatatype dt; 1796 public RdpDatatype Datatype { 1797 get { return dt; } 1798 } 1799 1800 string value; 1801 public string Value { 1802 get { return value; } 1803 } 1804 1805 public override bool Nullable { 1806 get { return false; } 1807 } 1808 1809 internal override bool IsTextValueDependent { 1810 get { return true; } 1811 } 1812 1813 internal override bool IsContextDependent { 1814 get { return dt.IsContextDependent; } 1815 } 1816 1817 public override RelaxngPatternType PatternType { 1818 get { return RelaxngPatternType.Value; } 1819 } 1820 1821 public override RdpContentType ContentType { 1822 get { return RdpContentType.Simple; } 1823 } 1824 GetLabels(LabelList elements, LabelList attributes, bool collectNameClass)1825 public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass) 1826 { 1827 // do nothing 1828 } 1829 1830 string cachedValue; 1831 RdpPattern cachedPattern; 1832 TextDeriv(string s, XmlReader reader)1833 public override RdpPattern TextDeriv (string s, XmlReader reader) 1834 { 1835 if (s == cachedValue && !IsContextDependent) 1836 return cachedPattern; 1837 cachedPattern = TextDerivCore (s, reader); 1838 cachedValue = s; 1839 return cachedPattern; 1840 } 1841 TextDerivCore(string s, XmlReader reader)1842 RdpPattern TextDerivCore (string s, XmlReader reader) 1843 { 1844 if (dt.IsTypeEqual (value, s, reader)) 1845 return RdpEmpty.Instance; 1846 else 1847 return RdpNotAllowed.Instance; 1848 } 1849 MarkReachableDefs()1850 internal override void MarkReachableDefs () 1851 { 1852 // do nothing 1853 } 1854 CheckConstraints(bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)1855 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept) 1856 { 1857 // nothing to be checked 1858 } 1859 ContainsText()1860 internal override bool ContainsText() 1861 { 1862 return false; 1863 } 1864 } 1865 1866 // Attribute 1867 public class RdpAttribute : RdpPattern 1868 { RdpAttribute(RdpNameClass nameClass, RdpPattern p)1869 public RdpAttribute (RdpNameClass nameClass, RdpPattern p) 1870 { 1871 this.nameClass = nameClass; 1872 this.children = p; 1873 } 1874 1875 RdpNameClass nameClass; 1876 public RdpNameClass NameClass { 1877 get { return nameClass; } 1878 } 1879 1880 RdpPattern children; 1881 public RdpPattern Children { 1882 get { return children; } 1883 set { children = value; } 1884 } 1885 1886 public override bool Nullable { 1887 get { return false; } 1888 } 1889 1890 internal override bool IsTextValueDependent { 1891 get { return false; } 1892 } 1893 1894 internal override bool IsContextDependent { 1895 get { return false; } 1896 } 1897 1898 public override RelaxngPatternType PatternType { 1899 get { return RelaxngPatternType.Attribute; } 1900 } 1901 1902 public override RdpContentType ContentType { 1903 get { return RdpContentType.Empty; } 1904 } 1905 GetLabels(LabelList elements, LabelList attributes, bool collectNameClass)1906 public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass) 1907 { 1908 if (attributes != null) { 1909 if (collectNameClass) 1910 attributes [NameClass] = NameClass; 1911 else 1912 AddNameLabel (attributes, NameClass); 1913 } 1914 } 1915 1916 bool isExpanded; ExpandRef(Hashtable defs)1917 internal override RdpPattern ExpandRef (Hashtable defs) 1918 { 1919 if (!isExpanded) { 1920 isExpanded = true; 1921 children = children.ExpandRef (defs); 1922 } 1923 return this; 1924 } 1925 ReduceEmptyAndNotAllowed(ref bool result, Hashtable visited)1926 internal override RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited) 1927 { 1928 if (visited.Contains (this)) 1929 return this; 1930 visited.Add (this, this); 1931 1932 if (children.PatternType == RelaxngPatternType.NotAllowed) { 1933 result = true; 1934 return RdpNotAllowed.Instance; 1935 } else { 1936 children = children.ReduceEmptyAndNotAllowed (ref result, visited); 1937 return this; 1938 } 1939 } 1940 1941 // attDeriv cx (Attribute nc p) (AttributeNode qn s) = 1942 // if contains nc qn && valueMatch cx p s then Empty else NotAllowed AttDeriv(string name, string ns, string value, XmlReader reader)1943 public override RdpPattern AttDeriv (string name, string ns, string value, XmlReader reader) 1944 { 1945 // If value is null, then does not check ValueMatch. 1946 #if UseStatic 1947 if (RdpUtil.Contains (this.nameClass, att.QName) 1948 && (value == null || RdpUtil.ValueMatch (ctx, this.children, att.Value))) 1949 return RdpEmpty.Instance; 1950 else 1951 return RdpNotAllowed.Instance; 1952 #else 1953 if (nameClass.Contains (name, ns) && 1954 (value == null || children.ValueMatch (value, reader))) 1955 return RdpEmpty.Instance; 1956 else 1957 return RdpNotAllowed.Instance; 1958 #endif 1959 } 1960 StartAttDeriv(string name, string ns)1961 public override RdpPattern StartAttDeriv (string name, string ns) 1962 { 1963 return nameClass.Contains (name, ns) ? 1964 children.After (RdpEmpty.Instance) : RdpNotAllowed.Instance; 1965 } 1966 StartAttDeriv(string name, string ns, MemoizationStore memo)1967 internal override RdpPattern StartAttDeriv (string name, string ns, MemoizationStore memo) 1968 { 1969 return nameClass.Contains (name, ns) ? 1970 children.After (RdpEmpty.Instance) : RdpNotAllowed.Instance; 1971 } 1972 1973 // startTagCloseDeriv (Attribute _ _) = NotAllowed StartTagCloseDeriv()1974 public override RdpPattern StartTagCloseDeriv () 1975 { 1976 return RdpNotAllowed.Instance; 1977 } 1978 StartTagCloseDeriv(MemoizationStore memo)1979 internal override RdpPattern StartTagCloseDeriv (MemoizationStore memo) 1980 { 1981 return RdpNotAllowed.Instance; 1982 } 1983 MarkReachableDefs()1984 internal override void MarkReachableDefs () 1985 { 1986 children.MarkReachableDefs (); 1987 } 1988 CheckConstraints(bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)1989 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept) 1990 { 1991 // 7.1.1 and 7.1.2 1992 if (attribute || oneOrMoreGroup || oneOrMoreInterleave || list || dataExcept) 1993 throw new RelaxngException ("Not allowed attribute occurence was specified in the pattern."); 1994 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."); 1998 1999 this.Children.CheckConstraints (true, oneOrMore, false, false, false, false); 2000 } 2001 ContainsText()2002 internal override bool ContainsText() 2003 { 2004 // This method is to detect text pattern inside interleave child. 2005 // return children.ContainsText (); 2006 return false; 2007 } 2008 } 2009 2010 // Element 2011 public class RdpElement : RdpPattern 2012 { RdpElement(RdpNameClass nameClass, RdpPattern p)2013 public RdpElement (RdpNameClass nameClass, RdpPattern p) 2014 { 2015 this.nameClass = nameClass; 2016 this.children = p; 2017 } 2018 2019 RdpNameClass nameClass; 2020 public RdpNameClass NameClass { 2021 get { return nameClass; } 2022 } 2023 2024 RdpPattern children; 2025 public RdpPattern Children { 2026 get { return children; } 2027 set { children = value; } 2028 } 2029 2030 public override bool Nullable { 2031 get { return false; } 2032 } 2033 2034 internal override bool IsTextValueDependent { 2035 get { return false; } 2036 } 2037 2038 internal override bool IsContextDependent { 2039 get { return false; } 2040 } 2041 2042 public override RelaxngPatternType PatternType { 2043 get { return RelaxngPatternType.Element; } 2044 } 2045 2046 bool contentTypeCheckDone; 2047 public override RdpContentType ContentType { 2048 get { 2049 if (!contentTypeCheckDone) { 2050 contentTypeCheckDone = true; 2051 RdpContentType ct = children.ContentType; // conformance required. 2052 } 2053 return RdpContentType.Complex; 2054 } 2055 } 2056 GetLabels(LabelList elements, LabelList attributes, bool collectNameClass)2057 public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass) 2058 { 2059 if (elements != null) { 2060 if (collectNameClass) 2061 elements [NameClass] = NameClass; 2062 else 2063 AddNameLabel (elements, NameClass); 2064 } 2065 } 2066 2067 2068 bool isExpanded; 2069 short expanding; // FIXME: It is totally not required, but there is 2070 // some bugs in simplification and without it it causes infinite loop. ExpandRef(Hashtable defs)2071 internal override RdpPattern ExpandRef (Hashtable defs) 2072 { 2073 if (!isExpanded) { 2074 isExpanded = true; 2075 if (expanding == 100) 2076 throw new RelaxngException (String.Format ("Invalid recursion was found. Name is {0}", nameClass)); 2077 expanding++; 2078 children = children.ExpandRef (defs); 2079 expanding--; 2080 } 2081 return this; 2082 } 2083 ReduceEmptyAndNotAllowed(ref bool result, Hashtable visited)2084 internal override RdpPattern ReduceEmptyAndNotAllowed (ref bool result, Hashtable visited) 2085 { 2086 if (visited.Contains (this)) 2087 return this; 2088 visited.Add (this, this); 2089 2090 children = children.ReduceEmptyAndNotAllowed (ref result, visited); 2091 return this; 2092 } 2093 TextOnlyDeriv()2094 internal override RdpPattern TextOnlyDeriv () 2095 { 2096 return RdpNotAllowed.Instance; 2097 } 2098 TextOnlyDeriv(MemoizationStore memo)2099 internal override RdpPattern TextOnlyDeriv (MemoizationStore memo) 2100 { 2101 return RdpNotAllowed.Instance; 2102 } 2103 StartTagOpenDeriv(string name, string ns)2104 public override RdpPattern StartTagOpenDeriv (string name, string ns) 2105 { 2106 #if UseStatic 2107 if (RdpUtil.Contains (this.nameClass, qname)) 2108 return RdpUtil.After (this.Children, RdpEmpty.Instance); 2109 else 2110 return RdpNotAllowed.Instance; 2111 #else 2112 return nameClass.Contains (name, ns) ? 2113 children.After (RdpEmpty.Instance) : 2114 RdpNotAllowed.Instance; 2115 #endif 2116 } 2117 StartTagOpenDeriv(string name, string ns, MemoizationStore memo)2118 internal override RdpPattern StartTagOpenDeriv (string name, string ns, MemoizationStore memo) 2119 { 2120 return nameClass.Contains (name, ns) ? 2121 children.After (RdpEmpty.Instance) : 2122 RdpNotAllowed.Instance; 2123 } 2124 MarkReachableDefs()2125 internal override void MarkReachableDefs () 2126 { 2127 children.MarkReachableDefs (); 2128 } 2129 2130 bool constraintsChecked; CheckConstraints(bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)2131 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept) 2132 { 2133 if (constraintsChecked) 2134 return; 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); 2139 } 2140 ContainsText()2141 internal override bool ContainsText() 2142 { 2143 return false; 2144 } 2145 } 2146 2147 // After 2148 public class RdpAfter : RdpAbstractBinary 2149 { RdpAfter(RdpPattern l, RdpPattern r)2150 public RdpAfter (RdpPattern l, RdpPattern r) : base (l, r) 2151 { 2152 } 2153 2154 public override bool Nullable { 2155 get { return false; } 2156 } 2157 2158 internal override bool IsTextValueDependent { 2159 get { return LValue.IsTextValueDependent; } 2160 } 2161 2162 internal override bool IsContextDependent { 2163 get { return LValue.IsContextDependent; } 2164 } 2165 GetLabels(LabelList elements, LabelList attributes, bool collectNameClass)2166 public override void GetLabels (LabelList elements, LabelList attributes, bool collectNameClass) 2167 { 2168 LValue.GetLabels (elements, attributes, collectNameClass); 2169 } 2170 TextDeriv(string s, XmlReader reader)2171 public override RdpPattern TextDeriv (string s, XmlReader reader) 2172 { 2173 return LValue.TextDeriv (s, reader).After (RValue); 2174 } 2175 TextDeriv(string s, XmlReader reader, MemoizationStore memo)2176 internal override RdpPattern TextDeriv (string s, XmlReader reader, MemoizationStore memo) 2177 { 2178 return memo.TextDeriv (LValue, s, reader).After (RValue); 2179 } 2180 EmptyTextDeriv(MemoizationStore memo)2181 internal override RdpPattern EmptyTextDeriv (MemoizationStore memo) 2182 { 2183 return memo.EmptyTextDeriv (LValue).After (RValue); 2184 } 2185 TextOnlyDeriv()2186 internal override RdpPattern TextOnlyDeriv () 2187 { 2188 return LValue.TextOnlyDeriv ().After (RValue); 2189 } 2190 TextOnlyDeriv(MemoizationStore memo)2191 internal override RdpPattern TextOnlyDeriv (MemoizationStore memo) 2192 { 2193 return memo.TextOnlyDeriv (LValue).After (RValue); 2194 } 2195 MixedTextDeriv()2196 internal override RdpPattern MixedTextDeriv () 2197 { 2198 return LValue.MixedTextDeriv ().After (RValue); 2199 } 2200 MixedTextDeriv(MemoizationStore memo)2201 internal override RdpPattern MixedTextDeriv (MemoizationStore memo) 2202 { 2203 return memo.MixedTextDeriv (LValue).After (RValue); 2204 } 2205 2206 // startTagOpenDeriv (After p1 p2) qn = 2207 // applyAfter (flip after p2) (startTagOpenDeriv p1 qn) StartTagOpenDeriv(string name, string ns)2208 public override RdpPattern StartTagOpenDeriv (string name, string ns) 2209 { 2210 RdpPattern handled = LValue.StartTagOpenDeriv (name, ns); 2211 RdpFlip f = MakeFlip (RdpUtil.AfterFunction, RValue); 2212 return handled.ApplyAfter (new RdpApplyAfterHandler ( 2213 f.Apply)); 2214 } 2215 StartTagOpenDeriv(string name, string ns, MemoizationStore memo)2216 internal override RdpPattern StartTagOpenDeriv (string name, string ns, MemoizationStore memo) 2217 { 2218 RdpPattern handled = memo.StartTagOpenDeriv (LValue, name, ns); 2219 RdpFlip f = MakeFlip (RdpUtil.AfterFunction, RValue); 2220 return handled.ApplyAfter (new RdpApplyAfterHandler ( 2221 f.Apply)); 2222 } 2223 ApplyAfter(RdpApplyAfterHandler handler)2224 public override RdpPattern ApplyAfter (RdpApplyAfterHandler handler) 2225 { 2226 return LValue.After (handler (RValue)); 2227 } 2228 2229 // attDeriv cx (After p1 p2) att = 2230 // after (attDeriv cx p1 att) p2 AttDeriv(string name, string ns, string value, XmlReader reader)2231 public override RdpPattern AttDeriv (string name, string ns, string value, XmlReader reader) 2232 { 2233 return LValue.AttDeriv (name, ns, value, reader).After (RValue); 2234 } 2235 StartAttDeriv(string name, string ns)2236 public override RdpPattern StartAttDeriv (string name, string ns) 2237 { 2238 RdpPattern handled = LValue.StartAttDeriv (name, ns); 2239 RdpFlip f = MakeFlip (RdpUtil.AfterFunction, RValue); 2240 return handled.ApplyAfter (new RdpApplyAfterHandler ( 2241 f.Apply)); 2242 } 2243 StartAttDeriv(string name, string ns, MemoizationStore memo)2244 internal override RdpPattern StartAttDeriv (string name, string ns, MemoizationStore memo) 2245 { 2246 RdpPattern handled = memo.StartAttDeriv (LValue, name, ns); 2247 RdpFlip f = MakeFlip (RdpUtil.AfterFunction, RValue); 2248 return handled.ApplyAfter (new RdpApplyAfterHandler ( 2249 f.Apply)); 2250 } 2251 EndAttDeriv()2252 public override RdpPattern EndAttDeriv () 2253 { 2254 return LValue.Nullable ? RValue : RdpNotAllowed.Instance; 2255 } 2256 StartTagCloseDeriv()2257 public override RdpPattern StartTagCloseDeriv () 2258 { 2259 return LValue.StartTagCloseDeriv ().After (RValue); 2260 } 2261 StartTagCloseDeriv(MemoizationStore memo)2262 internal override RdpPattern StartTagCloseDeriv (MemoizationStore memo) 2263 { 2264 return memo.StartTagCloseDeriv (LValue).After (RValue); 2265 } 2266 EndTagDeriv()2267 public override RdpPattern EndTagDeriv () 2268 { 2269 return LValue.Nullable ? RValue : RdpNotAllowed.Instance; 2270 } 2271 2272 public override RelaxngPatternType PatternType { 2273 get { return RelaxngPatternType.After; } 2274 } 2275 MarkReachableDefs()2276 internal override void MarkReachableDefs () 2277 { 2278 throw new InvalidOperationException (); 2279 } 2280 CheckConstraints(bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept)2281 internal override void CheckConstraints (bool attribute, bool oneOrMore, bool oneOrMoreGroup, bool oneOrMoreInterleave, bool list, bool dataExcept) 2282 { 2283 throw new InvalidOperationException (); 2284 } 2285 ContainsText()2286 internal override bool ContainsText () 2287 { 2288 throw new InvalidOperationException (); 2289 } 2290 } 2291 } 2292 2293