// 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. } }
// 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; } }