private static void InitContextProvider( Grammar grammar, CilContextProvider cilProvider, ForeignContextProvider provider) { provider.Joint.Add(cilProvider); foreach (var cilContext in cilProvider.Contexts) { ForeignContext context; if (grammar.Contexts.FindOrAdd(cilContext.UniqueName, out context)) { context.Joint.Add(cilContext); } provider.Add(context); } }
public CilGrammar(CilGrammarSource source, ILogging logging) { Type definitionType = source.DefinitionType; GlobalContextProvider = new CilContextProvider(definitionType); this.IsValid = true; var startMeta = MetadataParser.EnumerateAndBind(definitionType); if (startMeta.Count() == 0) { throw new InvalidOperationException( string.Format( "No metadata found in language definition '{0}'", definitionType.FullName)); } this.SymbolResolver = new CilSymbolRefResolver(); this.Start = CilSymbolRef.Create(typeof(void)); var collector = new MetadataCollector(logging); collector.AddSymbol(Start); foreach (var meta in startMeta) { collector.AddMeta(meta); } if (collector.HasInvalidData) { this.IsValid = false; } this.metadata = collector.Metadata; this.productions = collector.Productions; foreach (var tid in collector.Symbols) { SymbolResolver.Link(tid); } var categories = new [] { SymbolCategory.Beacon, SymbolCategory.DoNotInsert, SymbolCategory.DoNotDelete, SymbolCategory.ExplicitlyUsed }; foreach (var category in categories) { foreach (var symbol in metadata.SelectMany(m => m.GetSymbolsInCategory(category))) { var def = SymbolResolver.Resolve(symbol); def.Categories |= category; } } if (productions.Count == 0) { throw new InvalidOperationException( string.Format( "Language definition '{0}' should have at least one parse production", definitionType.FullName)); } this.mergers = metadata .SelectMany(meta => meta.GetMergers(collector.Symbols)) .ToArray(); var terminals = collector.Symbols.Except(productions.Select(r => r.Outcome).Distinct()).ToArray(); var scanDataCollector = new ScanDataCollector(terminals, logging); scanDataCollector.AddCondition(definitionType); if (scanDataCollector.HasInvalidData) { this.IsValid = false; } conditions = scanDataCollector.Conditions; LinkRelatedTokens(conditions); var allTerms = (from t in scanDataCollector.Terminals let def = SymbolResolver.Resolve(t) where def != null select def) .Distinct(); var termsProducedByScanner = (from cond in scanDataCollector.Conditions from prod in cond.Matchers from outcome in prod.AllOutcomes let def = SymbolResolver.Resolve(outcome) where def != null select def) .Distinct(); var undefinedTerminals = allTerms .Where(symbol => !IsSpecialSymbol(symbol)) .Except(termsProducedByScanner); CheckAllScanRulesDefined(undefinedTerminals, source.Origin, logging); precedence = metadata.SelectMany(m => m.GetSymbolPrecedence()).ToList(); LocalContextProviders = metadata.SelectMany((m, index) => m.GetLocalContextProviders()); this.Reports = metadata.SelectMany(m => m.GetReports()).ToArray(); }