コード例 #1
0
        public Grammar Read(IGrammarSource source, ILogging logging)
        {
            var cilSource = source as CilGrammarSource;

            if (cilSource == null)
            {
                return(null);
            }

            this.logging = logging;

            CilGrammar definition = null;

            logging.WithTimeLogging(
                cilSource.LanguageName,
                cilSource.Origin,
                () =>
            {
                definition = new CilGrammar(cilSource, logging);
            },
                "parsing language definition");

            if (definition == null || !definition.IsValid)
            {
                return(null);
            }

            var grammar = BuildGrammar(definition);

            grammar.Options = (IronText.Reflection.RuntimeOptions)Attributes.First <LanguageAttribute>(cilSource.DefinitionType).Flags;
            return(grammar);
        }
コード例 #2
0
        private static Grammar BuildGrammar(CilGrammar definition)
        {
            var result = new Grammar();

            InitContextProvider(
                result,
                definition.GlobalContextProvider,
                result.GlobalContextProvider);

            var symbolResolver = definition.SymbolResolver;

            // Define grammar tokens
            foreach (var cilSymbol in symbolResolver.Definitions)
            {
                Symbol symbol;
                if (cilSymbol.Type == typeof(Exception))
                {
                    cilSymbol.Symbol = symbol = (Symbol)result.Symbols[PredefinedTokens.Error];
                    symbol.Joint.Add(
                        new CilSymbol
                    {
                        Type       = typeof(Exception),
                        Symbol     = symbol,
                        Categories = SymbolCategory.DoNotDelete | SymbolCategory.DoNotInsert
                    });
                }
                else
                {
                    symbol = new Symbol(cilSymbol.Name)
                    {
                        Categories = cilSymbol.Categories,
                        Joint      = { cilSymbol }
                    };
                    result.Symbols.Add(symbol);
                    cilSymbol.Symbol = symbol;
                }
            }

            foreach (CilSymbolFeature <Precedence> feature in definition.Precedence)
            {
                var symbol = symbolResolver.GetSymbol(feature.SymbolRef);
                symbol.Precedence = feature.Value;
            }

            foreach (CilSymbolFeature <CilContextProvider> feature in definition.LocalContextProviders)
            {
                var symbol = symbolResolver.GetSymbol(feature.SymbolRef);
                if (symbol != null)
                {
                    InitContextProvider(result, feature.Value, symbol.LocalContextProvider);
                }
            }

            result.Start = symbolResolver.GetSymbol(definition.Start);

            // Define grammar rules
            foreach (var cilProduction in definition.Productions)
            {
                Symbol outcome = symbolResolver.GetSymbol(cilProduction.Outcome);
                var    pattern = Array.ConvertAll(cilProduction.Pattern, symbolResolver.GetSymbol);

                // Try to find existing rules whith same token-signature
                Production production;
                if (result.Productions.FindOrAdd(outcome, pattern, out production))
                {
                    ForeignContextRef contextRef = CreateActionContextRef(cilProduction.Context);
                    production.Actions.Add(new ForeignAction(pattern.Length, contextRef));
                }

                var action = production.Actions[0];
                action.Joint.Add(cilProduction);

                production.ExplicitPrecedence = cilProduction.Precedence;
            }

            // Create conditions to allow referencing them from matchers
            foreach (CilCondition cilCondition in definition.Conditions)
            {
                var cond = CreateCondtion(result, cilCondition);
                result.Conditions.Add(cond);
            }

            // Create matchers
            foreach (CilCondition cilCondition in definition.Conditions)
            {
                var condition = ConditionFromType(result, cilCondition.ConditionType);

                foreach (var cilMatcher in cilCondition.Matchers)
                {
                    SymbolBase outcome = GetMatcherOutcomeSymbol(result, symbolResolver, cilMatcher.MainOutcome, cilMatcher.AllOutcomes);

                    var matcher = new Matcher(
                        cilMatcher.Pattern,
                        outcome,
#if false
                        context: CreateActionContextRef(cilMatcher.Context),
#endif
                        nextCondition: ConditionFromType(result, cilMatcher.NextConditionType),
                        disambiguation: cilMatcher.Disambiguation);
                    matcher.Joint.Add(cilMatcher);

                    condition.Matchers.Add(matcher);
                }
            }

            foreach (var cilMerger in definition.Mergers)
            {
                var symbol = symbolResolver.GetSymbol(cilMerger.Symbol);
                var merger = new Merger(symbol)
                {
                    Joint = { cilMerger }
                };
                result.Mergers.Add(merger);
            }

            foreach (var report in definition.Reports)
            {
                result.Reports.Add(report);
            }

            return(result);
        }