Esempio n. 1
0
        // Compile from this simplified syntax to derivatives.
        internal override RdpPattern Compile(RelaxngGrammar grammar)
        {
            ResetCompileState();

            parentGrammar = grammar;

            // First, process includes and divs. RELAX NG 4.1 - 4.15.
            ArrayList compiledDivs = new ArrayList();

            foreach (RelaxngInclude inc in includes)
            {
                compiledDivs.Add(inc.Compile(this));
            }
            compiledDivs.AddRange(divs);
            foreach (RelaxngDiv div in compiledDivs)
            {
                div.Compile(this);
            }

            // Check constraints. RELAX NG 4.16
            foreach (RelaxngStart start in starts)
            {
                start.Pattern.CheckConstraints();
            }
            foreach (RelaxngDefine define in defs)
            {
                foreach (RelaxngPattern p in define.Patterns)
                {
                    p.CheckConstraints();
                }
            }

            // Assemble combine into the same name defines/start.
            // see RELAX NG 4.17.
            AssembleCombine();

            // 4.18 : <grammar> must have at least one <start>.
            if (assembledStart == null)
            {
                throw new RelaxngException("A grammar elements must contain at least one start element.");
            }
            compiledStart = assembledStart.Compile(this);

            // Assemble all define components into top grammar and
            // return start patterns for descendant grammars.
            // see RELAX NG 4.18.
            CollectGrammars();
            if (parentGrammar != null)
            {
                return(compiledStart);
            }
            assembledStart = null; // no use anymore

            // 4.19 (a) remove non-reachable defines

            /*
             *                      compiledStart.MarkReachableDefs ();
             *                      ArrayList tmp = new ArrayList ();
             *                      foreach (DictionaryEntry entry in this.assembledDefs)
             *                              if (!reachableDefines.ContainsKey (entry.Key))
             *                                      tmp.Add (entry.Key);
             *                      foreach (string key in tmp)
             *                              assembledDefs.Remove (key);
             */
            // 4.19 (b) check illegal recursion
            CheckRecursion(compiledStart, 0);
            // here we collected element-replaced definitions
            foreach (DictionaryEntry entry in elementReplacedDefs)
            {
                assembledDefs.Add(entry.Key, entry.Value);
            }
            startPattern = compiledStart;
            // 4.20,21 reduce notAllowed and empty.
            bool b;

            do
            {
                b            = false;
                startPattern = startPattern.ReduceEmptyAndNotAllowed(ref b, new Hashtable());
            }while (b);

            Hashtable ht = new Hashtable();

            startPattern.setInternTable(ht);

            // Check Constraints: RELAX NG spec 7
            // 7.1.1-4, 7.3, 7.4
            startPattern.CheckConstraints(false, false, false, false, false, false);
            // 7.1.5
            CheckStartPatternContent(startPattern);

            // 4.19 (c) expandRef - actual replacement
            startPattern = compiledStart.ExpandRef(assembledDefs);

            // 7.2
            RdpContentType ct = startPattern.ContentType;

            // return its start pattern.
            IsCompiled = true;
            return(startPattern);
        }