Beispiel #1
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[]));
    }
Beispiel #2
0
 private void Closure(InternalNode node) {
   if (stack.Count > 0) {
     ContentNode topNode = (ContentNode)stack.Pop();
     if (isPartial && !topNode.IsTerminal) {
       // need to reach in and wrap _pRight hand side of element.
       // and n remains the same.
       InternalNode inNode = (InternalNode)topNode;
       node.LeftChild = inNode.RightChild;
       node.Parent = inNode;
       if (inNode.RightChild != null) {
         inNode.RightChild.Parent = node;
       }
       inNode.RightChild = node;
     }
     else {
       // wrap terminal or any node
       if (topNode != null) topNode.Parent = node;
       node.LeftChild = topNode;
       topNode = node;
     }
     stack.Push(topNode);
   }
   else {
     // wrap whole content
     node.LeftChild = contentNode;
     contentNode.Parent = node;
     contentNode = node;
   }
 }
Beispiel #3
0
 public ParticleContentValidator(XmlSchemaContentType contentType, NamedNode[] namedTerminals, Hashtable symbols, InternalNode contentRoot, NamedNode endMarker, int symbolCount, Member mixed) : base(contentType, mixed) {
   this.namedTerminals = namedTerminals;
   this.symbols = symbols;
   this.contentRoot = contentRoot;
   this.endMarker = endMarker;
   this.symbolCount = symbolCount;
 }
Beispiel #4
0
    public ContentValidator Finish(ValidationState context, bool compile) {
      Debug.Assert(contentType == XmlSchemaContentType.ElementOnly || contentType == XmlSchemaContentType.Mixed);
      if (contentNode == null) {
        if (contentType == XmlSchemaContentType.Mixed) {
          string ctype = IsOpen ? "Any" : "TextOnly";
          return IsOpen ? ContentValidator.Any : 
            new ContentValidator(XmlSchemaContentType.TextOnly, this.MixedMember);
        }
        else {
          Debug.Assert(!IsOpen);
          return ContentValidator.Empty;
        }
      }

      // add end node
      contentRoot = new SequenceNode(null,null);
      contentNode.Parent = contentRoot;
      contentRoot.LeftChild = contentNode;

      endMarker = NewNamedTerminal(Identifier.Empty, null, null);
      endMarker.Parent = contentRoot;
      contentRoot.RightChild = endMarker;

      namedTerminals = (NamedNode[])namedTerminalsArray.ToArray(typeof(NamedNode));
      namedTerminalsArray = null;

      contentRoot.ConstructPos(namedTerminals.Length);

      // bugbug: I need to figure out how to get the real terminals
      // back out of the state machine.  Currently the state machine treats all terminals
      // with the same name as the same terminal, which is not what I want.  I need
      // the NamedNode with the right member bindings.
      if (canCompile && compile) {
        return new CompiledParticleContentValidator(context, this.contentRoot, this.namedTerminals, 
          this.symbols, this.symbolCount, this.IsOpen, this.contentType, this.MixedMember, endMarker);
      } 
      else {
        Debug.Assert(!IsOpen); // only deal with compiled XDR open content model
        return new ParticleContentValidator(this.contentType, this.namedTerminals, this.symbols,
          this.contentRoot, this.endMarker, this.symbolCount, this.MixedMember);
      }
    }