示例#1
0
        // remove ref and parentRef.
        // add new defines for each elements.
        private void CheckReferences(RdpPattern p)
        {
            RdpAbstractBinary binary = p as RdpAbstractBinary;

            if (binary != null)
            {
                // choice, interleave, group
                CheckReferences(binary.LValue);
                CheckReferences(binary.RValue);
                return;
            }
            RdpAbstractSingleContent single = p as RdpAbstractSingleContent;

            if (single != null)
            {
                CheckReferences(single.Child);
                return;
            }

            switch (p.PatternType)
            {
            case RelaxngPatternType.Ref:
                // FIXME: This should not re-expand ref
                RdpUnresolvedRef pref = p as RdpUnresolvedRef;
                if (pref.RefPattern != null)
                {
                    break;
                }

                RelaxngGrammar target = pref.TargetGrammar;
                if (target == null)
                {
                    // FIXME: fill line info
                    throw new RelaxngException("Referenced definition was not found.");
                }
                RdpPattern defP = target.assembledDefs [pref.Name] as RdpPattern;
                if (defP == null)
                {
                    target.unresolvedPatterns.Add(p);
                }
                else
                {
                    ArrayList al = target.refPatterns [defP] as ArrayList;
                    if (al == null)
                    {
                        al = new ArrayList();
                        target.refPatterns [defP] = al;
                    }
                    al.Add(p);
                    pref.RefPattern = defP;
                }
                break;

            case RelaxngPatternType.Attribute:
                CheckReferences(((RdpAttribute)p).Children);
                break;

            case RelaxngPatternType.DataExcept:
                CheckReferences(((RdpDataExcept)p).Except);
                break;

            case RelaxngPatternType.Element:
                RdpElement el = p as RdpElement;
                CheckReferences(el.Children);
                string name = ElementDefMap [el] as string;
                if (name == null)
                {
                    // add new define
                    int    idx     = 0;
                    string newName = "element0";
                    if (el.NameClass is RdpName)
                    {
                        newName = ((RdpName)el.NameClass).LocalName;
                    }
                    while (true)
                    {
                        if (assembledDefs [newName] == null)
                        {
                            elementReplacedDefs [newName] = el.Children;
                            break;
                        }
                        newName = "element" + ++idx;
                    }
                    ElementDefMap [el] = newName;
                }
                // Even though the element is replaced with ref,
                // derivative of ref is RdpElement in fact...
                break;

            case RelaxngPatternType.List:
                CheckReferences(((RdpList)p).Child);
                break;

            case RelaxngPatternType.Empty:
            case RelaxngPatternType.NotAllowed:
            case RelaxngPatternType.Text:
            case RelaxngPatternType.Value:
                break;

                //case RelaxngPatternType.ExternalRef:
                //case RelaxngPatternType.Include:
                // Mixed, Optional, ZeroOrMore are already removed.
                // Choice, Group, Interleave, OneOrMore are already proceeded.
            }
        }
示例#2
0
        // 4.19 (b)
        private void CheckRecursion(RdpPattern p, int depth)
        {
            RdpAbstractBinary binary = p as RdpAbstractBinary;

            if (binary != null)
            {
                // choice, interleave, group
                CheckRecursion(binary.LValue, depth);
                CheckRecursion(binary.RValue, depth);
                return;
            }
            RdpAbstractSingleContent single = p as RdpAbstractSingleContent;

            if (single != null)
            {
                CheckRecursion(single.Child, depth);
                return;
            }

            switch (p.PatternType)
            {
            case RelaxngPatternType.Ref:
                // get checkRecursionDepth from table.
                int    checkRecursionDepth = -1;
                object checkedDepth        = checkedDefs [p];
                if (checkedDepth != null)
                {
                    checkRecursionDepth = (int)checkedDepth;
                }
                // get refPattern
                RdpUnresolvedRef pref       = p as RdpUnresolvedRef;
                RelaxngGrammar   target     = pref.TargetGrammar;
                RdpPattern       refPattern = pref.RefPattern;
                if (refPattern == null)
                {
                    // FIXME: fill line info
                    throw new RelaxngException("No matching define found for " + pref.Name);
                }

                if (checkRecursionDepth == -1)
                {
                    checkedDefs [p] = depth;
                    /*test*/
                    if (refPattern.PatternType != RelaxngPatternType.Element)
                    {
                        CheckRecursion(refPattern, depth);
                    }
                    checkedDefs [p] = -2;
                }
                else if (depth == checkRecursionDepth)
                {
                    // FIXME: fill line info
                    throw new RelaxngException(String.Format("Detected illegal recursion. Ref name is {0}.", pref.Name));
                }

                break;

            case RelaxngPatternType.Attribute:
                CheckRecursion(((RdpAttribute)p).Children, depth);
                break;

            case RelaxngPatternType.DataExcept:
                CheckRecursion(((RdpDataExcept)p).Except, depth);
                break;

            case RelaxngPatternType.Element:
                RdpElement el = p as RdpElement;
                CheckRecursion(el.Children, depth + 1); // +1
                break;

            case RelaxngPatternType.List:
                CheckRecursion(((RdpList)p).Child, depth);
                break;
            }
        }