Пример #1
0
        public void AddSymbol(CilSymbolRef token)
        {
            if (symbols.Contains(token))
            {
                return;
            }

            symbols.Add(token);

            // Provide new rules from existing meta
            var newTokens = new[] { token };

            foreach (var meta in validMetadata)
            {
                var newParseRules = meta.GetProductions(newTokens);
                foreach (var parseRule in newParseRules)
                {
                    this.AddProduction(meta, parseRule);
                }
            }

            // Provide new meta (DemandAttribute)
            if (!token.HasLiteral)
            {
                foreach (var meta in MetadataParser.EnumerateAndBind(token.Type))
                {
                    this.AddMeta(meta);
                }
            }
        }
Пример #2
0
        internal CilMatcher(Type outcomeType)
            : this()
        {
            var outcome = CilSymbolRef.Create(outcomeType);

            MainOutcome = outcome;
            AllOutcomes.Add(outcome);
        }
Пример #3
0
 public CilProduction(CilSymbolRef outcome, IEnumerable <CilSymbolRef> pattern, CilContextRef context, Pipe <IActionCode> actionBuilder, Precedence precedence = null)
 {
     this.Outcome       = outcome;
     this.Pattern       = pattern.ToArray();
     this.Context       = context;
     this.ActionBuilder = actionBuilder;
     this.Precedence    = precedence;
 }
        public CilSymbol Resolve(CilSymbolRef symbolRef)
        {
            if (symbolRef == null)
            {
                return(null);
            }

            var literalDef   = ResolveLiteral(symbolRef.Literal);
            var tokenTypeDef = ResolveTokenType(symbolRef.Type);

            if (literalDef != null && tokenTypeDef != null && literalDef != tokenTypeDef)
            {
                throw new InvalidOperationException("Unable to resolve conflicting token reference: " + symbolRef);
            }

            return(literalDef ?? tokenTypeDef);
        }
Пример #5
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);
        }
Пример #6
0
        private static SymbolBase GetMatcherOutcomeSymbol(
            Grammar grammar,
            ICilSymbolResolver symbolResolver,
            CilSymbolRef mainOutcome,
            IEnumerable <CilSymbolRef> allOutcomes)
        {
            Symbol main = symbolResolver.GetSymbol(mainOutcome);

            Symbol[] all = (from outcome in allOutcomes
                            select symbolResolver.GetSymbol(outcome))
                           .ToArray();

            switch (all.Length)
            {
            case 0:  return(null);

            case 1:  return(main);

            default: return(new AmbiguousSymbol(main, all));
            }
        }
        private CilSymbol Ensure(CilSymbolRef symbolRef)
        {
            CilSymbol literalDef = ResolveLiteral(symbolRef.Literal);
            CilSymbol typeDef    = ResolveTokenType(symbolRef.Type);
            CilSymbol def        = MergeDefs(literalDef, typeDef);

            if (def == null)
            {
                def = new CilSymbol();
            }
            else if (symbolRef.Type != null && def.Type != null && def.Type != symbolRef.Type)
            {
                throw new InvalidOperationException("Incompatible symbol constraints.");
            }

            // Add token to a defintion
            if (symbolRef.Type != null)
            {
                def.Type = symbolRef.Type;
            }

            if (symbolRef.HasLiteral)
            {
                def.Literals.Add(symbolRef.Literal);
            }

            // Update index
            foreach (var literal in def.Literals)
            {
                ref2def[literal] = def;
            }

            if (def.Type != null)
            {
                ref2def[def.Type] = def;
            }

            return(def);
        }
Пример #8
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();
        }
        public Symbol GetSymbol(CilSymbolRef tid)
        {
            CilSymbol def = Resolve(tid);

            return(def == null ? null : def.Symbol);
        }
Пример #10
0
 public bool Contains(CilSymbolRef symbolRef)
 {
     return(symbolRef != null &&
            (ResolveLiteral(symbolRef.Literal) != null ||
             ResolveTokenType(symbolRef.Type) != null));
 }
Пример #11
0
 public void Link(CilSymbolRef first)
 {
     Ensure(first);
 }