internal ProductionRuleTemplateArgumentSeries(IOilexerGrammarProductionRuleTemplateEntry entry, ITemplateReferenceProductionRuleItem reference) { TemplateArgumentInformation tai = entry.GetArgumentInformation(); if (tai.InvalidArguments > 0) { this.dynLookup = null; this.fixedLookup = null; this.Lookup = null; this.index = int.MinValue; return; } this.fixedLookup = new Dictionary <IProductionRuleTemplatePart, ArgumentData>(); if (tai.DynamicArguments > 0) { this.dynLookup = new IDictionary <IProductionRuleTemplatePart, ArgumentData> [(reference.Count - tai.FixedArguments) / tai.DynamicArguments]; } else { this.dynLookup = new IDictionary <IProductionRuleTemplatePart, ArgumentData> [0]; } for (int i = 0; i < tai.FixedArguments; i++) { fixedLookup.Add(entry.Parts[i], new ArgumentData(entry.Parts[i], reference[i])); } //Dynamic series index. for (int i = 0, dSerInd = 0; i < reference.Count - tai.FixedArguments; i += tai.DynamicArguments, dSerInd++) { dynLookup[dSerInd] = new Dictionary <IProductionRuleTemplatePart, ArgumentData>(); for (int j = i; j < i + tai.DynamicArguments; j++) { dynLookup[dSerInd].Add(entry.Parts[j - i], new ArgumentData(entry.Parts[j - i], reference[j])); } } this.Lookup = null; this.index = int.MinValue; }
public static IProductionRuleItem ResolveTemplateSoftReference<T>(this ISoftTemplateReferenceProductionRuleItem item, T entry, OilexerGrammarFile file, ICompilerErrorCollection errors) where T : IOilexerGrammarProductionRuleEntry { IOilexerGrammarProductionRuleTemplateEntry iprte = null; var closeMatches = GetList(new { Entry = (IOilexerGrammarProductionRuleTemplateEntry)null, ArgumentInformation = default(TemplateArgumentInformation) }); foreach (IOilexerGrammarProductionRuleTemplateEntry template in ruleTemplEntries) { if (template.Name == item.PrimaryName) { TemplateArgumentInformation tai = template.GetArgumentInformation(); if (item.Parts.Count >= tai.FixedArguments) { closeMatches.Add(new { Entry = template, ArgumentInformation = tai }); if (tai.DynamicArguments > 0) { if ((item.Parts.Count - tai.FixedArguments) % tai.DynamicArguments == 0) { if (tai.InvalidArguments == 0) { iprte = template; break; } } } else if (tai.InvalidArguments == 0) { if (item.Parts.Count == tai.FixedArguments) { iprte = template; break; } } } else { closeMatches.Add(new { Entry = template, ArgumentInformation = tai }); continue; } } } if (iprte != null) { foreach (IProductionRuleSeries iprs in item.Parts) iprs.ResolveProductionRuleSeries(entry, file, errors); TemplateReferenceProductionRuleItem rResult = new TemplateReferenceProductionRuleItem(iprte, new List<IProductionRuleSeries>(item.Parts.ToArray()), item.Column, item.Line, item.Position); if (resolutionAid != null) resolutionAid.ResolvedSinglePartToRuleTemplate(item, iprte); if (item.RepeatOptions != ScannableEntryItemRepeatInfo.None) rResult.RepeatOptions = item.RepeatOptions; if (item.Name != null && item.Name != string.Empty) rResult.Name = item.Name; return rResult; } else if (closeMatches.Count > 0) { var fixedMatch = (from templateArguments in closeMatches let arguments = templateArguments.ArgumentInformation where arguments.FixedArguments > 0 orderby arguments.FixedArguments descending select templateArguments.Entry); IOilexerGrammarProductionRuleTemplateEntry closestMismatch = null; foreach (var mismatch in fixedMatch) { if (item.Parts.Count > mismatch.Parts.Count) { closestMismatch = mismatch; break; } } /**/ if (closestMismatch == null) closestMismatch = fixedMatch.Last(); if (fixedMatch != null) errors.SourceModelError<ISoftTemplateReferenceProductionRuleItem, IOilexerGrammarProductionRuleTemplateEntry>(OilexerGrammarCore.CompilerErrors.FixedArgumentMismatch, new LineColumnPair(item.Line, item.Column), LineColumnPair.Zero, new Uri(entry.FileName, UriKind.RelativeOrAbsolute), item, closestMismatch, new string[] { closestMismatch.Name, closestMismatch.Parts.Count.ToString(), item.Parts.Count.ToString() }); else { var dynamicMatch = (from templateArguments in closeMatches let arguments = templateArguments.ArgumentInformation where arguments.DynamicArguments > 0 select templateArguments.Entry).FirstOrDefault(); if (dynamicMatch != null) errors.SourceModelError<IOilexerGrammarProductionRuleTemplateEntry>(OilexerGrammarCore.CompilerErrors.DynamicArgumentCountError, new LineColumnPair(item.Line, item.Column), LineColumnPair.Zero, new Uri(entry.FileName, UriKind.RelativeOrAbsolute), dynamicMatch); else { var invalidMatch = (from templateArguments in closeMatches let arguments = templateArguments.ArgumentInformation where arguments.InvalidArguments > 0 select templateArguments.Entry).FirstOrDefault(); if (invalidMatch != null) errors.SourceModelError<IOilexerGrammarProductionRuleTemplateEntry>(OilexerGrammarCore.CompilerErrors.InvalidRepeatOptions, new LineColumnPair(item.Line, item.Column), LineColumnPair.Zero, new Uri(entry.FileName, UriKind.RelativeOrAbsolute), invalidMatch); else if (ruleEntries.OilexerGrammarFindScannableEntry(item.PrimaryName) != null) errors.SourceModelError<ISoftTemplateReferenceProductionRuleItem>(OilexerGrammarCore.CompilerErrors.RuleNotTemplate, new LineColumnPair(item.Line, item.Column), LineColumnPair.Zero, new Uri(entry.FileName, UriKind.RelativeOrAbsolute), item, item.PrimaryName); } } //errors.Add(OilexerGrammarCore.GetParserError(entry.FileName, item.Line, item.Column, OilexerGrammarParserErrors.DynamicArgumentCountError)); } else if (ruleEntries.OilexerGrammarFindScannableEntry(item.PrimaryName) != null) errors.SourceModelError<ISoftTemplateReferenceProductionRuleItem>(OilexerGrammarCore.CompilerErrors.RuleNotTemplate, new LineColumnPair(item.Line, item.Column), LineColumnPair.Zero, new Uri(entry.FileName, UriKind.RelativeOrAbsolute), item, item.PrimaryName); else { var matches = (from template in ruleTemplEntries where template.Name == item.PrimaryName select template).Count(); if (matches > 0) errors.SourceError(OilexerGrammarCore.CompilerErrors.FixedArgumentMismatch, new LineColumnPair(item.Line, item.Column), LineColumnPair.Zero, new Uri(entry.FileName, UriKind.RelativeOrAbsolute), item.PrimaryName); else errors.SourceError(OilexerGrammarCore.CompilerErrors.UndefinedRuleReference, new LineColumnPair(item.Line, item.Column), LineColumnPair.Zero, new Uri(entry.FileName, UriKind.RelativeOrAbsolute), item.PrimaryName); } return item; } public static IProductionRuleItem ResolveSoftReference<T>(this ISoftReferenceProductionRuleItem item, T entry, OilexerGrammarFile file, ICompilerErrorCollection errors) where T : IOilexerGrammarProductionRuleEntry { if (entry is IOilexerGrammarProductionRuleTemplateEntry) { var templateEntry = entry as IOilexerGrammarProductionRuleTemplateEntry; if (string.IsNullOrEmpty(item.SecondaryName)) foreach (IProductionRuleTemplatePart iprtp in templateEntry.Parts) if (iprtp.Name == item.PrimaryName) { TemplateParamReferenceProductionRuleItem result = new TemplateParamReferenceProductionRuleItem(templateEntry, iprtp, item.Column, item.Line, item.Position); if (resolutionAid != null) resolutionAid.ResolvedSinglePartToTemplateParameter(templateEntry, iprtp, item); if (item.RepeatOptions != ScannableEntryItemRepeatInfo.None) result.RepeatOptions = item.RepeatOptions; if (item.Name != null && result.Name == null) result.Name = item.Name; return result; } } IOilexerGrammarProductionRuleEntry ipre = ruleEntries.OilexerGrammarFindScannableEntry(item.PrimaryName); if (ipre != null) { RuleReferenceProductionRuleItem rrpri = new RuleReferenceProductionRuleItem(ipre, item.Column, item.Line, item.Position); if (resolutionAid != null) resolutionAid.ResolvedSinglePartToRule(item, ipre); ((ProductionRuleItem)(item)).CloneData(rrpri); return rrpri; } else if (ruleTemplEntries.OilexerGrammarFindScannableEntry(item.PrimaryName) != null) errors.SourceModelError<ISoftReferenceProductionRuleItem>(OilexerGrammarCore.CompilerErrors.RuleIsTemplate, new LineColumnPair(item.Line, item.Column), LineColumnPair.Zero, new Uri(entry.FileName, UriKind.RelativeOrAbsolute), item, item.PrimaryName); else { IOilexerGrammarTokenEntry tokenE = tokenEntries.OilexerGrammarFindScannableEntry(item.PrimaryName); if (tokenE != null) if (item.SecondaryName != null) { ITokenItem iti = tokenE.FindTokenItem(item.SecondaryName); if (iti != null) { IProductionRuleItem result = null; if (iti is ILiteralCharTokenItem) { if (resolutionAid != null) resolutionAid.ResolvedDualPartToTokenItem(item, tokenE, iti); result = new LiteralCharReferenceProductionRuleItem(((ILiteralCharTokenItem)(iti)), tokenE, item.Column, item.Line, item.Position, item.IsFlag, item.Counter); } else if (iti is ILiteralStringTokenItem) { if (resolutionAid != null) resolutionAid.ResolvedDualPartToTokenItem(item, tokenE, iti); result = new LiteralStringReferenceProductionRuleItem(((ILiteralStringTokenItem)(iti)), tokenE, item.Column, item.Line, item.Position, item.IsFlag, item.Counter); } else { /* * * ToDo: Throw an error here for referencing the wrong type of token * */ } if (result != null) { result.Name = item.Name; result.RepeatOptions = item.RepeatOptions; return result; } }