public static IPreprocessorDirective ResolveProductionRuleItem<T>(this IPreprocessorDirective item, T entry, OilexerGrammarFile file, ICompilerErrorCollection errors) where T : IOilexerGrammarProductionRuleEntry { switch (item.Type) { case EntryPreprocessorType.If: case EntryPreprocessorType.IfNotDefined: case EntryPreprocessorType.IfDefined: case EntryPreprocessorType.ElseIf: case EntryPreprocessorType.ElseIfDefined: case EntryPreprocessorType.Else: IPreprocessorIfDirective ipid = ((IPreprocessorIfDirective)(item)); PreprocessorIfDirective pid = new PreprocessorIfDirective(item.Type, ((IPreprocessorIfDirective)item).Condition, entry.FileName, item.Column, item.Line, item.Position); foreach (IPreprocessorDirective ipd in ipid.Body) ((PreprocessorIfDirective.DirectiveBody)(pid.Body)).Add(ipd.ResolveProductionRuleItem(entry, file, errors)); if (ipid.Next != null) pid.Next = (IPreprocessorIfDirective)ipid.Next.ResolveProductionRuleItem(entry, file, errors); return pid; case EntryPreprocessorType.DefineRule: IPreprocessorDefineRuleDirective ipdd = ((IPreprocessorDefineRuleDirective)(item)); IProductionRule[] dr = new IProductionRule[ipdd.DefinedRules.Length]; for (int i = 0; i < ipdd.DefinedRules.Length; i++) { dr[i] = ipdd.DefinedRules[i].Clone(); dr[i].ResolveProductionRule(entry, file, errors); } return new PreprocessorDefineRuleDirective(ipdd.DeclareTarget, dr, ipdd.Column, ipdd.Line, ipdd.Position); case EntryPreprocessorType.AddRule: IPreprocessorAddRuleDirective ipard = ((IPreprocessorAddRuleDirective)(item)); IProductionRule[] ar = new IProductionRule[ipard.Rules.Length]; for (int i = 0; i < ipard.Rules.Length; i++) { ar[i] = ipard.Rules[i].Clone(); ar[i].ResolveProductionRule(entry, file, errors); } return new PreprocessorAddRuleDirective(ipard.InsertTarget, ar, ipard.Column, ipard.Line, ipard.Position); case EntryPreprocessorType.Throw: return item; case EntryPreprocessorType.Return: IPreprocessorConditionalReturnDirective ipcrd = ((IPreprocessorConditionalReturnDirective)(item)); IProductionRule[] crd = new IProductionRule[ipcrd.Result.Length]; for (int i = 0; i < ipcrd.Result.Length; i++) { crd[i] = ipcrd.Result[i].Clone(); crd[i].ResolveProductionRule(entry, file, errors); } return new PreprocessorConditionalReturnDirective(crd, ipcrd.Column, ipcrd.Line, ipcrd.Position); } return item; }
internal static void Expand(this IPreprocessorDefineRuleDirective directive, IOilexerGrammarProductionRuleEntry currentEntry, IList <IOilexerGrammarTokenEntry> availableStock, ProductionRuleTemplateArgumentSeries argumentLookup, IOilexerGrammarProductionRuleTemplateEntry entry, OilexerGrammarFile file, ICompilerErrorCollection errors) { string search = directive.DeclareTarget; if (search != null && search != string.Empty) { if (argumentLookup.ContainsParameter(search)) { IProductionRuleTemplatePart part = argumentLookup.GetParameter(search); IProductionRuleSeries iprs = argumentLookup[part]; if (iprs.Count == 1 && iprs[0].Count == 1) { IProductionRuleItem ipri = iprs[0][0]; if (ipri is ISoftReferenceProductionRuleItem) { ISoftReferenceProductionRuleItem n = (ISoftReferenceProductionRuleItem)ipri; search = n.PrimaryName; } } } /* ToDo: Evaluate the depth necessary to institute a lock associated to the base list on the oilexer grammar file type. */ IOilexerGrammarEntry[] fileElements; lock (file) fileElements = file.ToArray(); foreach (IOilexerGrammarEntry ie in fileElements) { if (ie is IOilexerGrammarNamedEntry && ((IOilexerGrammarNamedEntry)ie).Name == search) { errors.SourceError(OilexerGrammarCore.CompilerErrors.DuplicateTermDefined, new LineColumnPair(directive.Line, directive.Column), LineColumnPair.Zero, new Uri(entry.FileName, UriKind.RelativeOrAbsolute), search); return; } } OilexerGrammarProductionRuleEntry insertedItem = new OilexerGrammarProductionRuleEntry(search, entry.ScanMode, entry.FileName, directive.Column, directive.Line, directive.Position); lock (file) file.Add(insertedItem); foreach (IProductionRule ipr in directive.DefinedRules) { IProductionRule expanded = ipr.Expand(currentEntry, availableStock, argumentLookup, entry, file, errors); insertedItem.Add(expanded); } } }