// Name class analysis internal static bool NamesOverlap(RdpPattern p1, RdpPattern p2, bool checkElements) { if (p1 == p2) { return(true); } RdpAbstractBinary bp1 = p1 as RdpAbstractBinary; if (bp1 != null) { return(NamesOverlap(bp1.LValue, p2, checkElements) || NamesOverlap(bp1.RValue, p2, checkElements)); } RdpOneOrMore rp1 = p1 as RdpOneOrMore; if (rp1 != null) { return(NamesOverlap(rp1.Child, p2, checkElements)); } RdpAttribute ap1 = p1 as RdpAttribute; if (ap1 != null) { return(NamesOverlap(p2, ap1.NameClass, checkElements)); } if (!checkElements) { return(false); } RdpElement ep1 = p1 as RdpElement; if (ep1 != null) { return(NamesOverlap(p2, ep1.NameClass, checkElements)); } return(false); }
// Name class analysis static bool NamesOverlap(RdpPattern p1, RdpNameClass n, bool checkElements) { RdpAbstractBinary bp1 = p1 as RdpAbstractBinary; if (bp1 != null) { return(NamesOverlap(bp1.LValue, n, checkElements) || NamesOverlap(bp1.RValue, n, checkElements)); } RdpOneOrMore rp1 = p1 as RdpOneOrMore; if (rp1 != null) { return(NamesOverlap(rp1.Child, n, checkElements)); } RdpAttribute ap1 = p1 as RdpAttribute; if (ap1 != null) { return(NameClassOverlap(ap1.NameClass, n)); } if (!checkElements) { return(false); } RdpElement ep1 = p1 as RdpElement; if (ep1 != null) { return(NameClassOverlap(ep1.NameClass, n)); } return(false); }
// 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; } }
internal static string DebugRdpPattern(RdpPattern p, IDictionary <object, object> visitedPattern) { if (p is RdpText) { return("<text/>\n"); } if (p is RdpEmpty) { return("<empty/>\n"); } if (p is RdpNotAllowed) { return("<notAllowed/>\n"); } if (visitedPattern.ContainsKey(p)) { return("<" + p.PatternType + " ref='" + p.GetHashCode() + "'/>"); } visitedPattern.Add(p, p); string intl = "(id=" + p.GetHashCode() + ") "; RdpAbstractSingleContent s = p as RdpAbstractSingleContent; if (s != null) { intl = DebugRdpPattern(s.Child, visitedPattern); } RdpAbstractBinary b = p as RdpAbstractBinary; if (b != null) { intl = DebugRdpPattern(b.LValue, visitedPattern) + DebugRdpPattern(b.RValue, visitedPattern); } RdpData data = p as RdpData; if (data != null) { intl = String.Format("name={0},ns={1},type={2} {3}", data.Datatype.LocalName, data.Datatype.NamespaceURI, data.Datatype.GetType(), data is RdpDataExcept ? DebugRdpPattern(((RdpDataExcept)data).Except, visitedPattern) : String.Empty); } RdpValue value = p as RdpValue; if (value != null) { intl = String.Format("name={0},ns={1},value={2} type={3}", value.Datatype.LocalName, value.Datatype.NamespaceURI, value.Value, value.Datatype.GetType()); } RdpElement el = p as RdpElement; if (el != null) { intl = DebugNameClass(el.NameClass) + DebugRdpPattern(el.Children, visitedPattern); } RdpAttribute at = p as RdpAttribute; if (at != null) { intl = DebugNameClass(at.NameClass) + DebugRdpPattern(at.Children, visitedPattern); } string str = String.Format("<{0} id='id{1}'>\n{2}\n</{0}>", p.PatternType.ToString(), p.GetHashCode(), intl); return(str); }