public static void FinalLink(this IOilexerGrammarProductionRuleEntry entry, OilexerGrammarFile file, ICompilerErrorCollection errors) { if (entry.NeedsFinalLinking()) { List <IProductionRule> result = new List <IProductionRule>(); foreach (IProductionRule currentItem in entry) { IProductionRule resultIPR = null; if (currentItem.NeedsFinalLinking()) { resultIPR = currentItem.FinalLink(entry, file, errors); } else { resultIPR = currentItem; } if (resultIPR != null) { result.Add(resultIPR); } } OilexerGrammarProductionRuleEntry r = ((OilexerGrammarProductionRuleEntry)(entry)); r.Clear(); foreach (IProductionRule ipr in result) { r.Add(ipr); } } }
private static void ExpungeUnusedTokens(this OilexerGrammarFile file) { IList <IOilexerGrammarTokenEntry> tokenReferences = new List <IOilexerGrammarTokenEntry>(); foreach (IOilexerGrammarProductionRuleEntry rule in ruleEntries) { rule.GetTokenReferences(tokenReferences); } IList <IOilexerGrammarTokenEntry> unusedTokens = new List <IOilexerGrammarTokenEntry>(); foreach (IOilexerGrammarTokenEntry entry in file.GetTokenEnumerator()) { if (!tokenReferences.Contains(entry)) { if (entry.Unhinged || entry is IOilexerGrammarTokenEofEntry) { continue; } else { unusedTokens.Add(entry); } } } file.ExpungeSet(unusedTokens); }
private static void ResolveProductionRule<T>(this T entry, OilexerGrammarFile file, ICompilerErrorCollection errors) where T : IOilexerGrammarProductionRuleEntry { if (entry is IOilexerGrammarProductionRuleTemplateEntry) ((IOilexerGrammarProductionRuleTemplateEntry)(entry)).ResolveProductionRuleTemplate(file, errors); entry.ResolveProductionRuleSeries(entry, file, errors); }
private static void ExpungeSet <T>(this OilexerGrammarFile file, IList <T> list) where T : IOilexerGrammarEntry { foreach (T t in list) { file.Remove(t); } }
//private static IOilexerGrammarProductionRuleEntry currentEntry = null; public static void FinalLink(this OilexerGrammarFile file, ICompilerErrorCollection errors) { //currentEntry = null; IList <IOilexerGrammarProductionRuleEntry> original = ruleEntries.ToList(); //When '__EXTRACTED' is added, ruleEntries invalidates. var availableStock = file.GetTokens().Cast <IOilexerGrammarTokenEntry>().ToList(); foreach (IOilexerGrammarProductionRuleEntry rule in original) { GC.Collect(); GC.WaitForPendingFinalizers(); rule.Deliteralize(availableStock, file, errors); } file.ExpungeUnusedTokens(); foreach (IOilexerGrammarProductionRuleEntry rule in ruleEntries) { rule.FinalLink(file, errors); } var namedEntries = from s in file where s is IOilexerGrammarNamedEntry select(IOilexerGrammarNamedEntry) s; var namedDuplicates = (from s in namedEntries let duplicates = (from s2 in namedEntries where s != s2 where s.Name == s2.Name select s2).ToArray() where duplicates.Length > 0 select new { Entry = s, Duplicates = duplicates }); var passedDuplicates = new List <IOilexerGrammarNamedEntry>(); foreach (var duplLookup in namedDuplicates) { if (passedDuplicates.Contains(duplLookup.Entry)) { continue; } passedDuplicates.Add(duplLookup.Entry); var mainError = errors.SourceModelError(OilexerGrammarCore.CompilerErrors.DuplicateEntryError, new LineColumnPair(duplLookup.Entry.Line, duplLookup.Entry.Column), new LineColumnPair(duplLookup.Entry.Line, duplLookup.Entry.Column + duplLookup.Entry.Name.Length), new Uri(duplLookup.Entry.FileName, UriKind.RelativeOrAbsolute), duplLookup.Entry, new string[] { duplLookup.Entry.Name }); foreach (var duplicate in duplLookup.Duplicates) { passedDuplicates.Add(duplicate); errors.SourceModelError(OilexerGrammarCore.CompilerErrors.DuplicateEntryReference, new LineColumnPair(duplicate.Line, duplicate.Column), new LineColumnPair(duplicate.Line, duplicate.Column + duplicate.Name.Length), new Uri(duplicate.FileName, UriKind.RelativeOrAbsolute), duplicate, mainError, new string[] { duplicate.Name }); } } file.ExpungeComments(); foreach (var rule in ruleEntries) { if (rule.IsRuleCollapsePoint) { rule.ValidateCollapsePoint(errors); } } }
private static IList <T> GatherType <T>(this OilexerGrammarFile file) where T : IOilexerGrammarEntry { IList <T> list = new List <T>(); foreach (IOilexerGrammarEntry entry in file) { if (entry is T) { if (!(list.Contains((T)entry))) { list.Add((T)entry); } } } return(list); }
private static void ResolveToken(this IOilexerGrammarTokenEntry entry, OilexerGrammarFile file, ICompilerErrorCollection errors) { List<IOilexerGrammarTokenEntry> lowerTokens = new List<IOilexerGrammarTokenEntry>(); if (entry.LowerPrecedenceTokens == null) { foreach (var s in entry.LowerPrecedenceNames) { var match = (from generalEntry in tokenEntries let tokenEntry = generalEntry as IOilexerGrammarTokenEntry where tokenEntry != null && tokenEntry.Name == s.Name select tokenEntry).FirstOrDefault(); if (match == null) { errors.SourceModelError<IOilexerGrammarTokenEntry>(OilexerGrammarCore.CompilerErrors.UndefinedTokenReference, new LineColumnPair(s.Line, s.Column), new LineColumnPair(s.Line, s.Column + s.Name.Length), new Uri(entry.FileName, UriKind.RelativeOrAbsolute), entry, string.Format(@", lower precedence: '{0}'", s.Name)); break; } lowerTokens.Add(match); } ((OilexerGrammarTokenEntry)entry).LowerPrecedenceTokens = lowerTokens.ToArray(); } entry.Branches.ResolveTokenExpressionSeries(entry, file, errors); }
public static void ExpandTemplates(this OilexerGrammarFile file, ICompilerErrorCollection errors) { List <IOilexerGrammarProductionRuleEntry> rules = null; var toks = (from f in file where f is IOilexerGrammarTokenEntry select(IOilexerGrammarTokenEntry) f).ToList(); do { /* * * For grammars which generate a *lot* of changes in their * productions. * */ GC.Collect(); GC.WaitForPendingFinalizers(); rules = new List <IOilexerGrammarProductionRuleEntry>(ruleEntries); /* * * Expand the templates of every rule in the file. * Utilize a list to make the operating set * immutable and expansions won't affect the * enumeration. * */ var toExpand = (from r in rules where r.NeedsExpansion() select r); #if ParallelProcessing Parallel.ForEach(toExpand, rule => #else foreach (IOilexerGrammarProductionRuleEntry rule in toExpand) #endif { rule.ExpandTemplates(toks, file, errors); #if ParallelProcessing }); #else }
public static IProductionRulePreprocessorDirective ResolveProductionRuleItem<T>(this IProductionRulePreprocessorDirective item, T entry, OilexerGrammarFile file, ICompilerErrorCollection errors) where T : IOilexerGrammarProductionRuleEntry { return new ProductionRulePreprocessorDirective(item.Directive.ResolveProductionRuleItem(entry, file, errors), item.Column, item.Line, item.Position); }
private static void ResolveProductionRule<T>(this IProductionRule rule, T entry, OilexerGrammarFile file, ICompilerErrorCollection errors) where T : IOilexerGrammarProductionRuleEntry { /* * * Copy the source, can't use just a standard IEnumerable because by design * it only enumerates the source when requested. If we tamper with the source, * before enumerating the transitionFirst time, the results are distorted. * */ IList<IProductionRuleItem> rCopy = new List<IProductionRuleItem>(rule); ProductionRule pr = rule as ProductionRule; IEnumerable<IProductionRuleItem> finalVersion = from item in rCopy select (item.ResolveProductionRuleItem(entry, file, errors)); pr.BaseCollection.Clear(); foreach (IProductionRuleItem iti in finalVersion) pr.BaseCollection.Add(iti); }
private static IProductionRuleItem ResolveProductionRuleItem<T>(this IProductionRuleItem item, T entry, OilexerGrammarFile file, ICompilerErrorCollection errors) where T : IOilexerGrammarProductionRuleEntry { if (item is IProductionRuleGroupItem) { ((IProductionRuleGroupItem)(item)).ResolveProductionRuleSeries(entry, file, errors); return item; } else if (item is ILiteralProductionRuleItem) return item; else if (item is IProductionRulePreprocessorDirective) return ((IProductionRulePreprocessorDirective)item).ResolveProductionRuleItem(entry, file, errors); else if (item is ISoftTemplateReferenceProductionRuleItem) return ((ISoftTemplateReferenceProductionRuleItem)(item)).ResolveTemplateSoftReference(entry, file, errors); else if (item is ISoftReferenceProductionRuleItem) return ((ISoftReferenceProductionRuleItem)(item)).ResolveSoftReference(entry, file, errors); else return item; }
private static void ResolveProductionRuleTemplate(this IOilexerGrammarProductionRuleTemplateEntry entry, OilexerGrammarFile file, ICompilerErrorCollection errors) { foreach (ProductionRuleTemplatePart part in entry.Parts) { IOilexerGrammarTokenEntry reference = null; if (part.SpecialExpectancy == TemplatePartExpectedSpecial.None && part.ExpectedSpecific != null && part.ExpectedSpecific is ISoftReferenceProductionRuleItem) { var softExpect = part.ExpectedSpecific as ISoftReferenceProductionRuleItem; if ((reference = tokenEntries.OilexerGrammarFindScannableEntry(softExpect.PrimaryName)) != null) { part.ExpectedSpecific = new TokenReferenceProductionRuleItem(reference, part.Column, part.Line, part.Position); if (resolutionAid != null) resolutionAid.ResolvedSinglePartToToken(softExpect, reference); } else errors.SourceModelError<ISoftReferenceProductionRuleItem>(OilexerGrammarCore.CompilerErrors.UndefinedTokenReference, new LineColumnPair(part.ExpectedSpecific.Column, part.ExpectedSpecific.Line), LineColumnPair.Zero, new Uri(entry.FileName, UriKind.RelativeOrAbsolute), softExpect, string.Format(" '{0}'", softExpect.PrimaryName)); return; } } }
private static void ResolveProductionRuleSeries<T>(this IProductionRuleSeries series, T entry, OilexerGrammarFile file, ICompilerErrorCollection errors) where T : IOilexerGrammarProductionRuleEntry { foreach (IProductionRule ite in series) ite.ResolveProductionRule(entry, file, errors); }
internal static bool Evaluate(this IPreprocessorCLogicalAndConditionExp expression, IOilexerGrammarProductionRuleEntry currentEntry, IList <IOilexerGrammarTokenEntry> availableStock, ProductionRuleTemplateArgumentSeries argumentLookup, IOilexerGrammarProductionRuleTemplateEntry entry, OilexerGrammarFile file, ICompilerErrorCollection errors) { //rule 2. if (expression.Left == null) { try { return((bool)expression.Right.Evaluate(currentEntry, availableStock, argumentLookup, entry, file, errors)); } catch { errors.SourceError(OilexerGrammarCore.CompilerErrors.InvalidPreprocessorCondition, new LineColumnPair(expression.Line, expression.Column), LineColumnPair.Zero, new Uri(entry.FileName, UriKind.RelativeOrAbsolute), expression.ToString()); } } //rule 1. else { return((bool)expression.Left.Evaluate(currentEntry, availableStock, argumentLookup, entry, file, errors) && (bool)expression.Right.Evaluate(currentEntry, availableStock, argumentLookup, entry, file, errors)); } return(false); }
internal static IProductionRuleItem Expand(this IPreprocessorDirective directive, IOilexerGrammarProductionRuleEntry currentEntry, IList <IOilexerGrammarTokenEntry> availableStock, ProductionRuleTemplateArgumentSeries argumentLookup, IOilexerGrammarProductionRuleTemplateEntry entry, OilexerGrammarFile file, ICompilerErrorCollection errors) { switch (directive.Type) { case EntryPreprocessorType.If: case EntryPreprocessorType.IfNotDefined: case EntryPreprocessorType.IfDefined: case EntryPreprocessorType.ElseIf: case EntryPreprocessorType.ElseIfDefined: case EntryPreprocessorType.Else: return(((IPreprocessorIfDirective)directive).Expand(currentEntry, availableStock, argumentLookup, entry, file, errors)); case EntryPreprocessorType.DefineRule: ((IPreprocessorDefineRuleDirective)(directive)).Expand(currentEntry, availableStock, argumentLookup, entry, file, errors); break; case EntryPreprocessorType.AddRule: ((IPreprocessorAddRuleDirective)(directive)).Expand(currentEntry, availableStock, argumentLookup, entry, file, errors); break; case EntryPreprocessorType.Throw: ((IPreprocessorThrowDirective)(directive)).Expand(currentEntry, availableStock, argumentLookup, entry, file, errors); break; case EntryPreprocessorType.Return: return(((IPreprocessorConditionalReturnDirective)(directive)).Expand(currentEntry, availableStock, argumentLookup, entry, file, errors)); } return(null); }
internal static object Evaluate(this IPreprocessorCPrimary expression, IOilexerGrammarProductionRuleEntry currentEntry, IList <IOilexerGrammarTokenEntry> availableStock, ProductionRuleTemplateArgumentSeries argumentLookup, IOilexerGrammarProductionRuleTemplateEntry entry, OilexerGrammarFile file, ICompilerErrorCollection errors) { switch (expression.Rule) { case 1: return(expression.String); case 2: return(expression.Char); case 3: return(expression.PreCLogicalOrExp.Evaluate(currentEntry, availableStock, argumentLookup, entry, file, errors)); case 4: return(expression.Identifier.Name); case 5: return(expression.Number); } return(null); }
private static void ResolveSoftReference(this ICommandTokenItem source, IOilexerGrammarTokenEntry entry, OilexerGrammarFile file, ICompilerErrorCollection errors) { if (source is IScanCommandTokenItem) { var scanSource = source as ScanCommandTokenItem; scanSource.SearchTarget.ResolveTokenExpressionSeries(entry, file, errors); } else if (source is ISubtractionCommandTokenItem) { var subtractSource = source as SubtractionCommandTokenItem; subtractSource.Left.ResolveTokenExpressionSeries(entry, file, errors); subtractSource.Right.ResolveTokenExpressionSeries(entry, file, errors); } else if (source is IBaseEncodeGraphCommand) { var graph = source as BaseEncodeGraphCommand; graph.EncodeTarget.ResolveTokenExpressionSeries(entry, file, errors); } }
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); } } }
private static void ResolveTokenExpression(this ITokenExpression expression, IOilexerGrammarTokenEntry entry, OilexerGrammarFile file, ICompilerErrorCollection errors) { IList<ITokenItem> rCopy = (from item in expression select item).ToList(); TokenExpression te = expression as TokenExpression; IEnumerable<ITokenItem> finalVersion = from item in rCopy select (item.ResolveTokenExpressionItem(entry, file, errors)); te.BaseCollection.Clear(); foreach (ITokenItem iti in finalVersion) te.BaseCollection.Add(iti); }
internal static void Expand(this IPreprocessorAddRuleDirective directive, IOilexerGrammarProductionRuleEntry currentEntry, IList <IOilexerGrammarTokenEntry> availableStock, ProductionRuleTemplateArgumentSeries argumentLookup, IOilexerGrammarProductionRuleTemplateEntry entry, OilexerGrammarFile file, ICompilerErrorCollection errors) { string search = directive.InsertTarget; if (search != null && search != string.Empty) { OilexerGrammarProductionRuleEntry foundItem = null; 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; } else if (ipri is IRuleReferenceProductionRuleItem) { foundItem = (OilexerGrammarProductionRuleEntry)((IRuleReferenceProductionRuleItem)(ipri)).Reference; } } } if (foundItem == null) { foreach (IOilexerGrammarEntry ie in file) { if (ie is OilexerGrammarProductionRuleEntry && ((OilexerGrammarProductionRuleEntry)ie).Name == search) { foundItem = ie as OilexerGrammarProductionRuleEntry; break; } } } if (foundItem == null) { errors.SourceError(OilexerGrammarCore.CompilerErrors.UndefinedAddRuleTarget, new LineColumnPair(directive.Line, directive.Column), LineColumnPair.Zero, new Uri(entry.FileName, UriKind.RelativeOrAbsolute), string.Join <IProductionRule>(" | ", directive.Rules), search); return; } foreach (IProductionRule ipr in directive.Rules) { foundItem.Add(ipr.Expand(currentEntry, availableStock, argumentLookup, entry, file, errors)); } } }
internal static IProductionRuleItem Expand(this IPreprocessorConditionalReturnDirective directive, IOilexerGrammarProductionRuleEntry currentEntry, IList <IOilexerGrammarTokenEntry> availableStock, ProductionRuleTemplateArgumentSeries argumentLookup, IOilexerGrammarProductionRuleTemplateEntry entry, OilexerGrammarFile file, ICompilerErrorCollection errors) { IProductionRule[] result = new IProductionRule[directive.Result.Length]; for (int i = 0; i < directive.Result.Length; i++) { result[i] = directive.Result[i].Expand(currentEntry, availableStock, argumentLookup, entry, file, errors); } var resultG = new ProductionRuleGroupItem(result, directive.Column, directive.Line, directive.Position); return(resultG); }
internal static void Expand(this IPreprocessorThrowDirective directive, IOilexerGrammarProductionRuleEntry currentEntry, IList <IOilexerGrammarTokenEntry> availableStock, ProductionRuleTemplateArgumentSeries argumentLookup, IOilexerGrammarProductionRuleTemplateEntry entry, OilexerGrammarFile file, ICompilerErrorCollection errors) { string[] errorData = new string[directive.Arguments.Length]; int index = 0; //List<Tuple<string, int, int>> errorLocations = new List<Tuple<string, int, int>>(); List <Tuple <IProductionRule, ISoftReferenceProductionRuleItem> > errorLocations = new List <Tuple <IProductionRule, ISoftReferenceProductionRuleItem> >(); foreach (var item in directive.Arguments) { if (item.TokenType == OilexerGrammarTokenType.Identifier) { var idItem = item as OilexerGrammarTokens.IdentifierToken; if (!argumentLookup.ContainsParameter(idItem.Name)) { errorData[index++] = idItem.Name; continue; } else { var parameter = argumentLookup.GetParameter(idItem.Name); var parameterDataSeries = argumentLookup[parameter]; if (parameterDataSeries.Count == 1 && parameterDataSeries[0].Count == 1) { var pd0 = parameterDataSeries[0]; var parameterData = pd0[0]; if (parameterData is ISoftReferenceProductionRuleItem) { var specificData = (ISoftReferenceProductionRuleItem)parameterData; if (specificData.SecondaryToken == null) { errorData[index] = specificData.PrimaryName; } else { errorData[index] = string.Format("{0}.{1}", specificData.PrimaryName, specificData.SecondaryName); } errorLocations.Add(Tuple.Create(pd0, specificData)); } } } } else if (item.TokenType == OilexerGrammarTokenType.CharacterLiteral) { errorData[index] = ((OilexerGrammarTokens.CharLiteralToken)(item)).GetCleanValue().ToString(); } else if (item.TokenType == OilexerGrammarTokenType.StringLiteral) { errorData[index] = ((OilexerGrammarTokens.StringLiteralToken)(item)).GetCleanValue(); } index++; } if (errorLocations.Count > 0) { foreach (var errorLocation in errorLocations) { errors.SourceModelError(OilexerGrammarCore.CompilerErrors.LanguageDefinedError, new LineColumnPair(errorLocation.Item2.Line, errorLocation.Item2.Column), new LineColumnPair(errorLocation.Item2.Line, errorLocation.Item2.Column + (errorLocation.Item2.SecondaryToken == null ? errorLocation.Item2.PrimaryName.Length : errorLocation.Item2.PrimaryName.Length + errorLocation.Item2.SecondaryName.Length)), new Uri(errorLocation.Item1.FileName, UriKind.RelativeOrAbsolute), directive, errorLocation.Item1, errorLocation.Item2, new string[] { directive.Reference.Number.ToString(), string.Format(directive.Reference.Message, errorData) }); } } else { errors.SourceError(OilexerGrammarCore.CompilerErrors.LanguageDefinedError, new LineColumnPair(directive.Line, directive.Column), LineColumnPair.Zero, new Uri(entry.FileName, UriKind.RelativeOrAbsolute), directive.Reference.Number.ToString(), string.Format(directive.Reference.Message, errorData)); } }
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; }
private static ITokenItem ResolveSoftReference(this ISoftReferenceTokenItem item, IOilexerGrammarTokenEntry entry, OilexerGrammarFile file, ICompilerErrorCollection errors) { IOilexerGrammarTokenEntry tokenE = tokenEntries.OilexerGrammarFindScannableEntry(item.PrimaryName); if (tokenE != null) { if (item.SecondaryName != null) { ITokenItem iti = tokenE.FindTokenItem(item.SecondaryName); if (iti != null) { if (iti is ILiteralCharTokenItem) { LiteralCharReferenceTokenItem result = new LiteralCharReferenceTokenItem(tokenE, ((ILiteralCharTokenItem)(iti)), item.Column, item.Line, item.Position); if (!(string.IsNullOrEmpty(item.Name))) result.Name = item.Name; if (resolutionAid != null) resolutionAid.ResolvedDualPartToTokenItem(item, tokenE, iti); return result; } else if (iti is ILiteralStringTokenItem) { LiteralStringReferenceTokenItem result = new LiteralStringReferenceTokenItem(tokenE, ((ILiteralStringTokenItem)(iti)), item.Column, item.Line, item.Position); if (!(string.IsNullOrEmpty(item.Name))) result.Name = item.Name; if (resolutionAid != null) resolutionAid.ResolvedDualPartToTokenItem(item, tokenE, iti); return result; } else { errors.SourceModelError<ISoftReferenceTokenItem>(OilexerGrammarCore.CompilerErrors.UndefinedTokenReference, new LineColumnPair(item.Line, item.Column), new LineColumnPair(item.Line, item.Column + item.PrimaryName.Length), new Uri(entry.FileName, UriKind.RelativeOrAbsolute), item, string.Format(" '{0}'", item.PrimaryName)); } } } else { TokenReferenceTokenItem result = new TokenReferenceTokenItem(tokenE, item.Column, item.Line, item.Position); ((SoftReferenceTokenItem)(item)).CloneData(result); if (resolutionAid != null) resolutionAid.ResolvedSinglePartToToken(item, tokenE); return result; } } else if (item.SecondaryName == null) errors.SourceModelError<ISoftReferenceTokenItem>(OilexerGrammarCore.CompilerErrors.UndefinedTokenReference, new LineColumnPair(item.Line, item.Column), new LineColumnPair(item.Line, item.Column + item.PrimaryName.Length), new Uri(entry.FileName, UriKind.RelativeOrAbsolute), item, string.Format(" '{0}'", item.PrimaryName)); else errors.SourceModelError<ISoftReferenceTokenItem>(OilexerGrammarCore.CompilerErrors.UndefinedTokenReference, new LineColumnPair(item.Line, item.Column), new LineColumnPair(item.SecondaryToken.Line, item.SecondaryToken.Column + item.SecondaryToken.Length), new Uri(entry.FileName, UriKind.RelativeOrAbsolute), item, string.Format(" '{0}'", item.PrimaryName)); return item; }
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; } }
internal static object Evaluate(this IPreprocessorCEqualityExp expression, IOilexerGrammarProductionRuleEntry currentEntry, IList <IOilexerGrammarTokenEntry> availableStock, ProductionRuleTemplateArgumentSeries argumentLookup, IOilexerGrammarProductionRuleTemplateEntry entry, OilexerGrammarFile file, ICompilerErrorCollection errors) { IOilexerGrammarTokenEntry lookup; ILiteralTokenItem reference = null; //Hack #1. if (expression.Rule == 1 || expression.Rule == 2) { string name = null; //If the left side is a parameter reference and the right side //is an identifier... if (expression.PreCEqualityExp.Rule == 3 && expression.PreCPrimary.Rule == 4 && expression.PreCEqualityExp.PreCPrimary.Rule == 4 && argumentLookup.ContainsParameter(name = expression.PreCEqualityExp.PreCPrimary.Identifier.Name)) { //Obtain the parameter IProductionRuleTemplatePart part = argumentLookup.GetParameter(name); if (part.SpecialExpectancy == TemplatePartExpectedSpecial.None && part.ExpectedSpecific != null) { //If the specific expectency is a production rule reference... if (part.ExpectedSpecific is ITokenReferenceProductionRuleItem) { //Lookup the expectency. ILiteralTokenItem secondHalf = null; lookup = ((ITokenReferenceProductionRuleItem)(part.ExpectedSpecific)).Reference; //Lookup the right-hand requirement for the condition. ITokenItem sRef = lookup.FindTokenItem(expression.PreCPrimary.Identifier.Name); if (sRef is ILiteralTokenItem) { reference = ((ILiteralTokenItem)(sRef)); } else { goto notValidReference; } //Obtain the expression series for the left-hand side. IProductionRuleSeries series = argumentLookup[part]; //If it's a single unit. if (series.Count == 1 && series[0].Count == 1) { //If it's a soft-reference item... IProductionRuleItem e = series[0][0]; if (e is ISoftReferenceProductionRuleItem) { ISoftReferenceProductionRuleItem sre = ((ISoftReferenceProductionRuleItem)e); if (((sre.SecondaryName == null || sre.SecondaryName == string.Empty)) && sre.PrimaryName != null) { secondHalf = (ILiteralTokenItem)lookup.FindTokenItemByValue(sre.PrimaryName, file, true); } } //If they used the fully qualified name... else if (e is ILiteralReferenceProductionRuleItem) { ILiteralReferenceProductionRuleItem lr = ((ILiteralReferenceProductionRuleItem)e); //So much easier... secondHalf = lr.Literal; } if (expression.Rule == 1) { return(secondHalf == reference); } else if (expression.Rule == 2) { return(secondHalf != reference); } } } } } else if (expression.PreCEqualityExp.Rule == 3 && expression.PreCPrimary.Rule == 5 && expression.PreCEqualityExp.PreCPrimary.Rule == 4 && expression.PreCEqualityExp.PreCPrimary.Identifier.Name.ToLower() == "index") { if (expression.Rule == 1) { return(expression.PreCPrimary.Number.GetCleanValue() == argumentLookup.Index); } else if (expression.Rule == 2) { return(expression.PreCPrimary.Number.GetCleanValue() != argumentLookup.Index); } } } notValidReference: switch (expression.Rule) { case 1: //PreprocessorCEqualityExp "==" PreprocessorCPrimary return(expression.PreCEqualityExp.Evaluate(currentEntry, availableStock, argumentLookup, entry, file, errors) == expression.PreCPrimary.Evaluate(currentEntry, availableStock, argumentLookup, entry, file, errors)); case 2: //PreprocessorCEqualityExp "!=" PreprocessorCPrimary return(expression.PreCEqualityExp.Evaluate(currentEntry, availableStock, argumentLookup, entry, file, errors) != expression.PreCPrimary.Evaluate(currentEntry, availableStock, argumentLookup, entry, file, errors)); case 3: //PreprocessorCPrimary return(expression.PreCPrimary.Evaluate(currentEntry, availableStock, argumentLookup, entry, file, errors)); } return(false); }
private static void ResolveTokenExpressionSeries(this ITokenExpressionSeries series, IOilexerGrammarTokenEntry entry, OilexerGrammarFile file, ICompilerErrorCollection errors) { foreach (ITokenExpression ite in series) ite.ResolveTokenExpression(entry, file, errors); }
internal static bool IsDefined(this IPreprocessorCLogicalOrConditionExp expression, IOilexerGrammarProductionRuleEntry currentEntry, IList <IOilexerGrammarTokenEntry> availableStock, ProductionRuleTemplateArgumentSeries argumentLookup, IOilexerGrammarProductionRuleTemplateEntry entry, OilexerGrammarFile file, ICompilerErrorCollection errors) { if (expression.Left == null && expression.Right.Left == null && expression.Right.Right.Rule == 3 && expression.Right.Right.PreCPrimary.Rule == 4) { string name = expression.Right.Right.PreCPrimary.Identifier.Name; if (argumentLookup.ContainsParameter(name)) { IProductionRuleTemplatePart iprtp = argumentLookup.GetParameter(name); if (iprtp.SpecialExpectancy == TemplatePartExpectedSpecial.Rule) { IProductionRuleSeries iprs = argumentLookup[name]; if (iprs.Count == 1 && iprs[0].Count == 1) { IProductionRuleItem ipri = iprs[0][0]; if (ipri != null) { if (ipri is IRuleReferenceProductionRuleItem) { name = ((IRuleReferenceProductionRuleItem)(ipri)).Reference.Name; } else if (ipri is ISoftReferenceProductionRuleItem) { //No guarantee that just being a soft-reference guarantees //lack of definition. //Reason: if another template defines this later, //it exists, but hasn't been resolved. -- It will be later in the expansion/resolution phase. name = ((ISoftReferenceProductionRuleItem)(ipri)).PrimaryName; } } } } else { errors.SourceError(OilexerGrammarCore.CompilerErrors.IsDefinedTemplateParameterMustExpectRule, new LineColumnPair(expression.Line, expression.Column), LineColumnPair.Zero, new Uri(entry.FileName, UriKind.RelativeOrAbsolute), name); } } foreach (IOilexerGrammarEntry ientry in file.ToArray()) { if (ientry is IOilexerGrammarProductionRuleEntry && (!(ientry is IOilexerGrammarProductionRuleTemplateEntry))) { if (((IOilexerGrammarProductionRuleEntry)ientry).Name == name) { return(true); } } } return(false); } errors.SourceError(OilexerGrammarCore.CompilerErrors.InvalidDefinedTarget, new LineColumnPair(expression.Line, expression.Column), LineColumnPair.Zero, new Uri(entry.FileName, UriKind.RelativeOrAbsolute), expression.ToString()); return(false); }
private static ITokenItem ResolveTokenExpressionItem(this ITokenItem item, IOilexerGrammarTokenEntry entry, OilexerGrammarFile file, ICompilerErrorCollection errors) { if (item is ITokenGroupItem) { ((ITokenGroupItem)(item)).ResolveTokenExpressionSeries(entry, file, errors); return item; } else if (item is ISoftReferenceTokenItem) { return ((ISoftReferenceTokenItem)(item)).ResolveSoftReference(entry, file, errors); } else if (item is ICommandTokenItem) { ((ICommandTokenItem)(item)).ResolveSoftReference(entry, file, errors); return item; } else if (item is ILiteralStringTokenItem) { ILiteralStringTokenItem ilsti = ((ILiteralStringTokenItem)item); if (ilsti.Value.Length == 1) { LiteralCharTokenItem result = new LiteralCharTokenItem(ilsti.Value[0], ilsti.CaseInsensitive, ilsti.Column, ilsti.Line, ilsti.Position); ((LiteralStringTokenItem)(item)).CloneData(result); return result; } }//*/ return item; }
internal static void ExpandTemplates(this IOilexerGrammarProductionRuleEntry entry, IList <IOilexerGrammarTokenEntry> availableStock, OilexerGrammarFile file, ICompilerErrorCollection errors) { while (entry.NeedsExpansion()) { OilexerGrammarProductionRuleEntry e = ((OilexerGrammarProductionRuleEntry)(entry)); IProductionRuleSeries iprs = entry.ExpandTemplates(availableStock, entry, file, errors); e.Clear(); foreach (IProductionRule ipr in iprs) { e.Add(ipr); } } }