예제 #1
0
        internal CilMatcher(Type outcomeType)
            : this()
        {
            var outcome = CilSymbolRef.Create(outcomeType);

            MainOutcome = outcome;
            AllOutcomes.Add(outcome);
        }
예제 #2
0
        private static CilMatcher CreateImplicitLiteralMatcher(string literal)
        {
            var outcome = CilSymbolRef.Create(literal);

            // Generate implicit scan rule for the keyword
            var result = new CilMatcher
            {
                Context        = CilContextRef.None,
                MainOutcome    = outcome,
                AllOutcomes    = { outcome },
                Disambiguation = Disambiguation.Exclusive,
                Pattern        = ScanPattern.CreateLiteral(literal),
                ActionBuilder  = code => code
                                 .Emit(il => il.Ldnull())
                                 .ReturnFromAction()
            };

            return(result);
        }
예제 #3
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();
        }