Esempio n. 1
0
        internal override BitSet Firstpos(int positions)
        {
            if (first == null)
            {
                if ((contentType == Type.Sequence && left.Nullable()) || contentType == Type.Choice)
                {
                    first = (BitSet)left.Firstpos(positions).Clone();
                    first.Or(right.Firstpos(positions));
                }
                else
                {
                    first = left.Firstpos(positions);
                }
            }

            return(first);
        }
 private bool Accepts(ContentNode node, XmlQualifiedName qname, int positions, Object index)
 {
     if (index != null)
     {
         BitSet first = node.Firstpos(positions);
         for (int i = 0; i < first.Count; i++)
         {
             if (first.Get(i) && qname.Equals(((TerminalNode)terminalNodes[i]).Name))
             {
                 return(true);
             }
         }
         return(false);
     }
     else
     {
         return(node.Accepts(qname));
     }
 }
        internal void    Finish(ValidationEventHandler eventHandler, bool compile)
        {
            stack      = null;
            IsCompiled = !abnormalContent && compile;
            if (contentNode == null)
            {
                return;
            }

#if DEBUG
            StringBuilder bb = new StringBuilder();
            contentNode.Dump(bb);
            Debug.WriteLineIf(CompModSwitches.XmlSchema.TraceVerbose, "\t\t\tContent: (" + bb.ToString() + ")");
#endif

            // add end node
            endNode     = NewTerminalNode(XmlQualifiedName.Empty);
            contentNode = new InternalNode(contentNode, endNode, ContentNode.Type.Sequence);
            ((InternalNode)contentNode).LeftNode.ParentNode = contentNode;
            endNode.ParentNode = contentNode;

            if (!IsCompiled)
            {
                CheckXsdDeterministic(eventHandler);
                return;
            }

            if (nodeTable == null)
            {
                nodeTable = new Hashtable();
            }

            // calculate followpos
            int      terminals = terminalNodes.Count;
            BitSet[] followpos = new BitSet[terminals];
            for (int i = 0; i < terminals; i++)
            {
                followpos[i] = new BitSet(terminals);
            }
            contentNode.CalcFollowpos(followpos);

            // state table
            ArrayList Dstates = new ArrayList(16);
            // transition table
            dtrans = new ArrayList(16);
            // lists unmarked states
            ArrayList unmarked = new ArrayList(16);
            // state lookup table
            Hashtable statetable = new Hashtable();

            BitSet empty = new BitSet(terminals);
            statetable.Add(empty, -1);

            // start with firstpos at the root
            BitSet set = contentNode.Firstpos(terminals);
            statetable.Add(set, Dstates.Count);
            unmarked.Add(set);
            Dstates.Add(set);

            int[] a = new int[symbols.Count + 1];
            dtrans.Add(a);
            if (set.Get(endNode.Pos))
            {
                a[symbols.Count] = 1;   // accepting
            }

            // current state processed
            int state = 0;

            // check all unmarked states
            while (unmarked.Count > 0)
            {
                int[] t = (int[])dtrans[state];

                set = (BitSet)unmarked[0];
                CheckDeterministic(set, terminals, eventHandler);
                unmarked.RemoveAt(0);

                // check all input symbols
                for (int sym = 0; sym < symbols.Count; sym++)
                {
                    XmlQualifiedName n      = (XmlQualifiedName)symbols[sym];
                    BitSet           newset = new BitSet(terminals);

                    // if symbol is in the set add followpos to new set
                    for (int i = 0; i < terminals; i++)
                    {
                        if (set.Get(i) && n.Equals(((TerminalNode)terminalNodes[i]).Name))
                        {
                            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 = Dstates.Count;
                        statetable.Add(newset, transitionTo);
                        unmarked.Add(newset);
                        Dstates.Add(newset);
                        a = new int[symbols.Count + 1];
                        dtrans.Add(a);
                        if (newset.Get(endNode.Pos))
                        {
                            a[symbols.Count] = 1;   // accepting
                        }
                    }
                    else
                    {
                        transitionTo = (int)lookup;
                    }
                    // set the transition for the symbol
                    t[sym] = transitionTo;
                }
                state++;
            }

            nodeTable = null;
        }