Example #1
0
        private static void PlaceReduceActions(GrammarCompilationContext context)
        {
            foreach (var state in context.States)
            {
                var finalizers = state.Items.Finalizers;
                var finalizer = finalizers.FirstOrDefault();
                if (finalizers.Count == state.Items.Count && finalizers.All(x => x.Kernel.Reduction == finalizer.Kernel.Reduction))
                {
                    // State only has finalizers reducing to the same product.
                    state.State.DefaultAction = new ReduceParserAction(finalizer.Kernel.Reduction);
                }
                else
                {
                    // Determine what reduce action to apply based on the lookaheads.
                    foreach (var item in finalizers)
                    {
                        foreach (var lookahead in item.Lookahead)
                        {
                            var reduceAction = new ReduceParserAction(item.Kernel.Reduction);

                            ParserAction action;
                            if (!state.State.Actions.TryGetValue(lookahead, out action))
                            {
                                state.State.Actions[lookahead] = reduceAction;
                            }
                            else
                            {
                                // State already handles the lookahead, introduce reduce conflict.
                                context.Conflicts.Add(new GrammarReductionConflict(
                                    state.State,
                                    lookahead,
                                    action,
                                    reduceAction));
                            }
                        }
                    }
                }
            }
        }
 public GrammarCompilationResult(GrammarCompilationContext context, ParserAutomaton automaton)
 {
     CompilationContext = context;
     Automaton = automaton;
 }
Example #3
0
        private static void CreateLr0States(GrammarCompilationContext context)
        {
            foreach (var augmentedRoot in context.GrammarData.AugmentedRoots)
            {
                var initialState = CreateInitialState(context, augmentedRoot);
                context.InitialStates.Add(augmentedRoot, initialState);

                // Don't replace this with a foreach loop. States are being added on the fly.
                for (int i = 0; i < context.States.Count; i++)
                    ExpandState(context, context.States[i]);

                ReplaceRootReductionWithAcceptance(augmentedRoot, initialState);
            }
        }
Example #4
0
        private static void ExpandState(GrammarCompilationContext context, IntermediateParserState state)
        {
            // Check for possible shifts.
            foreach (var shifter in state.Items.Shifters)
            {
                var currentElement = shifter.Kernel.Element;

                // Get all LR(1) items sharing the same grammar element, get or
                // create the state that corresponds to the shifted items, and create
                // a transition to that state.
                var shiftedKernels = from item in state.Items
                    let kernel = item.Kernel
                    where kernel.Element == currentElement
                    select kernel.NextItem;
                var kernelsArray = shiftedKernels.ToArray();

                var nextState = context.GetOrCreateState(kernelsArray);
                shifter.NextItem = nextState.Items.First(x => x.Kernel == shifter.Kernel.NextItem);
                context.GetOrCreateTransition(state, currentElement, nextState);
                if (!state.State.Actions.ContainsKey(currentElement))
                {
                    var action = new ShiftParserAction(nextState.State);
                    var customActionElement = currentElement as CustomActionGrammarElement;
                    if (customActionElement != null)
                        action.CustomAction = customActionElement.Action;
                    state.State.Actions[currentElement] = action;
                }
            }
        }
Example #5
0
 private static IntermediateParserState CreateInitialState(GrammarCompilationContext context, GrammarDefinition augmentedRoot)
 {
     // The initial state contains the very first LR(0) item, which is the augmented root '.Root'.
     var initialItem = context.GrammarData.GrammarReductionsMapping[augmentedRoot][0].Lr0Items[0];
     var initialState = context.GetOrCreateState(new [] { initialItem });
     return initialState;
 }
Example #6
0
 private static ParserAutomaton CreateAutomaton(GrammarCompilationContext context)
 {
     var automaton = new ParserAutomaton(context.GrammarData.Grammar);
     foreach (var initialState in context.InitialStates)
         automaton.InitialStates.Add((GrammarDefinition)initialState.Key.Rule.Switch[0][0], initialState.Value.State);
     automaton.DefaultInitialState = context.InitialStates[context.GrammarData.DefaultAugmentedRoot].State;
     automaton.States.AddRange(context.States.Select(x => x.State));
     return automaton;
 }
Example #7
0
        private static void ConstructAugmentedGrammar(GrammarCompilationContext context)
        {
            // Augmented grammar is constructed as described in page 197 of
            // http://web.stanford.edu/class/archive/cs/cs143/cs143.1128/lectures/06/Slides06.pdf

            foreach (var state in context.States)
            {
                foreach (var item in state.Items)
                {
                    if (!item.Kernel.IsInitializer)
                        continue;

                    var reduction = new AugmentedGrammarReduction()
                    {
                        Product = context.GetOrCreateAnnotatedElement(item.Kernel.Reduction.Product,
                            state.OutgoingTransitions.GetOrDefault(item.Kernel.Reduction.Product)),
                        Reduction = item.Kernel.Reduction
                    };

                    for (var currentItem = item; !currentItem.Kernel.IsFinalizer; currentItem = currentItem.NextItem)
                    {
                        var element = currentItem.Kernel.Element;

                        ParserTransition transition = null;

                        var definition = element as GrammarDefinition;
                        if (definition != null)
                            transition = currentItem.State.OutgoingTransitions.GetOrDefault(element);

                        var annotatedElement = context.GetOrCreateAnnotatedElement(element, transition);
                        annotatedElement.Parents.Add(reduction);
                        reduction.Sequence.Add(annotatedElement);
                    }
                }
            }
        }
Example #8
0
        private static void ComputeLookaheads(GrammarCompilationContext context)
        {
            foreach (var state in context.States)
            {
                foreach (var item in state.Items)
                {
                    if (!item.Kernel.IsInitializer)
                        continue;

                    var finalizer = item.GetFinalizer();
                    if (finalizer.State.Items.Count == 1)
                        continue;

                    var annotatedElement = context.GetAnnotatedGrammarElement(item.Kernel.Reduction.Product, state);
                    if (annotatedElement!= null)
                        finalizer.Lookahead.UnionWith(annotatedElement.GetFollowSet());
                }
            }
        }
Example #9
0
        public static GrammarCompilationResult Compile(GrammarData grammarData)
        {
            if (grammarData == null)
                throw new ArgumentNullException(nameof(grammarData));

            var context = new GrammarCompilationContext(grammarData);
            CreateLr0States(context);
            ConstructAugmentedGrammar(context);
            ComputeLookaheads(context);
            PlaceReduceActions(context);

            var automaton = CreateAutomaton(context);
            var result = new GrammarCompilationResult(context, automaton);
            return result;
        }