예제 #1
0
    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;
    }
예제 #2
0
    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[]));
    }