예제 #1
0
        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);
            }
        }
예제 #2
0
        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();
        }
예제 #3
0
        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);
            }
        }