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;
                            }
                        }
示例#2
0
        internal static IProductionRuleItem Expand(this IProductionRuleItem ruleItem, IOilexerGrammarProductionRuleEntry currentEntry, IList <IOilexerGrammarTokenEntry> availableStock, ProductionRuleTemplateArgumentSeries argumentLookup, IOilexerGrammarProductionRuleTemplateEntry entry, OilexerGrammarFile file, ICompilerErrorCollection errors)
        {
            if (ruleItem is IProductionRulePreprocessorDirective)
            {
                return(((IProductionRulePreprocessorDirective)(ruleItem)).Expand(currentEntry, availableStock, argumentLookup, entry, file, errors));
            }
            else if (ruleItem is ITemplateParamReferenceProductionRuleItem)
            {
                TemplateParamReferenceProductionRuleItem trpri = (TemplateParamReferenceProductionRuleItem)ruleItem;
                if (argumentLookup.Lookup.ContainsKey(trpri.Reference))
                {
                    IProductionRuleSeries series = argumentLookup.Lookup[trpri.Reference].Replacement;

                    /* *
                     * Fix 4-29-2013
                     * *
                     * Series null check, if an error is thrown by the user's template within a replacement
                     * the result of the replacement is null, thus this is null.
                     * */
                    if (series == null)
                    {
                        return(null);
                    }
                    if (series.Count == 1 && series[0].Count == 1)
                    {
                        IProductionRuleItem ipri = series[0][0].Clone();
                        trpri.CloneData(ipri);
                        return(ipri);
                    }
                    else
                    {
                        ProductionRuleGroupItem result = new ProductionRuleGroupItem(series.ToArray(), trpri.Column, trpri.Line, trpri.Position);
                        trpri.CloneData(result);
                        return(result);
                    }
                }
                else
                {
                    return(trpri.Clone());
                }
            }
            else if (ruleItem is ITemplateReferenceProductionRuleItem)
            {
                ITemplateReferenceProductionRuleItem rI    = ruleItem as TemplateReferenceProductionRuleItem;
                List <IProductionRuleSeries>         serii = new List <IProductionRuleSeries>();
                foreach (IProductionRuleSeries series in rI)
                {
                    var seriesCopy = series;

                    /* *
                     * Handle deliteralization here to expedite
                     * phase 3.  If a template yields 5000 literals
                     * then deliteralizing that will waste a massive
                     * chunk of processor cycles.
                     * */
                    if (series.NeedsDeliteralized())
                    {
                        seriesCopy = seriesCopy.Deliteralize(currentEntry, availableStock, file, errors);
                    }
                    serii.Add(seriesCopy.Expand(currentEntry, availableStock, argumentLookup, entry, file, errors));
                }

                TemplateReferenceProductionRuleItem result = new TemplateReferenceProductionRuleItem(rI.Reference, serii, rI.Column, rI.Line, rI.Position);
                ((TemplateReferenceProductionRuleItem)ruleItem).CloneData(result);
                return(result.Expand(availableStock, entry, file, errors));
            }
            else if (ruleItem is IProductionRuleGroupItem)
            {
                if (!((IProductionRuleSeries)(ruleItem)).HasExpansion())
                {
                    return(ruleItem.Clone());
                }
                else
                {
                    ProductionRuleGroupItem result = new ProductionRuleGroupItem(((IProductionRuleSeries)ruleItem).Expand(currentEntry, availableStock, argumentLookup, entry, file, errors).ToArray(), ruleItem.Column, ruleItem.Line, ruleItem.Position);
                    result.RepeatOptions = ruleItem.RepeatOptions;
                    result.Name          = ruleItem.Name;
                    return(result);
                }
            }
            else
            {
                return(ruleItem.Clone());
            }
        }