protected bool Join(ValidationState context, NamedNode[] namedTerminals, BitSet lset, SchemaNamespaceList lany, BitSet rset, SchemaNamespaceList rany, out BitSet bitset, out SchemaNamespaceList wildcard) { wildcard = null; if (lset != null) { if (rset != null) { bitset = lset.Clone(); bitset.And(rset); if (!bitset.IsEmpty) { Identifier id = (context.Name == null) ? Identifier.Empty : context.Name; context.HandleError(this, id, Error.NonDeterministicAny, id.ToString()); return false; } bitset.Or(lset); bitset.Or(rset); } else { bitset = lset; } } else { bitset = rset; } if (lany != null) { if (rany != null) { SchemaNamespaceList list = SchemaNamespaceList.Intersection(rany, lany); if (list == null || list.IsEmpty()) { wildcard = SchemaNamespaceList.Union(rany, lany); } else { Identifier id = (context.Name == null) ? Identifier.Empty : context.Name; context.HandleError(this, id, Error.NonDeterministicAny, id.ToString()); return false; } } else { wildcard = lany; } } else { wildcard = rany; } if (wildcard != null && bitset != null) { for (int i = 0; i < bitset.Count; i++) { NamedNode node = namedTerminals[i]; if (bitset.Get(i) && wildcard.Allows(node)) { Identifier id = (context.Name == null ? node.Name : context.Name); context.HandleError(this, id, Error.NonDeterministicAny, id.ToString()); return false; } } } return true; }
internal CompiledParticleContentValidator(ValidationState context, InternalNode contentRoot, NamedNode[] namedTerminals, Hashtable symbols, int symCount, bool isOpen, XmlSchemaContentType contentType, Member mixed, NamedNode endMarker) : base(contentType, namedTerminals, symbols, contentRoot, endMarker, symCount, mixed) { // keep these this.isOpen = isOpen; this.isEmptiable = contentRoot.LeftChild.IsNullable; int terminalsCount = namedTerminals.Length; int endMarkerPos = terminalsCount - 1; // calculate followpos BitSet[] followpos = new BitSet[terminalsCount]; for (int i = 0; i < terminalsCount; i++) { followpos[i] = new BitSet(terminalsCount); } contentRoot.CalcFollowpos(followpos); // transition table ArrayList transitionTable = new ArrayList(); // state lookup table Hashtable stateTable = new Hashtable(); // lists unmarked states ArrayList unmarked = new ArrayList(); stateTable.Add(new BitSet(terminalsCount), -1); // add empty // start with firstpos at the root BitSet firstpos = contentRoot.Firstpos; stateTable.Add(firstpos, 0); unmarked.Add(firstpos); int[] a = new int[symbolCount + 1]; transitionTable.Add(a); if (firstpos[endMarkerPos]) { a[symbolCount] = 1; // accepting } // current state processed int state = 0; // check all unmarked states while (unmarked.Count > 0) { int[] t = (int[])transitionTable[state]; firstpos = (BitSet)unmarked[0]; if (!isNonDeterministic && !CheckDeterministic(firstpos, namedTerminals, context)) { isNonDeterministic = true; } unmarked.RemoveAt(0); // check all input symbols foreach (NamedNodeList list in symbols.Values){ foreach (NamedNode node in list) { BitSet newset = new BitSet(terminalsCount); // if symbol is in the set add followpos to new set for (int i = 0; i < terminalsCount; i++) { if (firstpos[i] && node == namedTerminals[i]) { newset.Or(followpos[i]); } } object lookup = stateTable[newset]; // this state will transition to int transitionTo; // if new set is not in states add it if (lookup == null) { transitionTo = stateTable.Count - 1; stateTable.Add(newset, transitionTo); unmarked.Add(newset); a = new int[symbolCount + 1]; transitionTable.Add(a); if (newset[endMarkerPos]) { a[symbolCount] = 1; // accepting } } else { transitionTo = (int)lookup; } // set the transition for the symbol t[node.Symbol] = transitionTo; } } state++; } // now convert transition table to array this.transitionTable = (int[][])transitionTable.ToArray(typeof(int[])); }