Пример #1
0
        public override void Apply(LanguageData language, LRItem owner)
        {
            var state        = owner.State;
            var allConflicts = state.BuilderData.Conflicts;

            if (allConflicts.Count == 0)
            {
                return;
            }
            //Find all conflicts that can be resolved by operator precedence
            // SL does not support Find extension, so we do it with explicit loop
            var operConflicts = new List <Terminal>();

            foreach (var c in allConflicts)
            {
                if (c.Flags.IsSet(TermFlags.IsOperator))
                {
                    operConflicts.Add(c);
                }
            }
            foreach (var conflict in operConflicts)
            {
                var newState    = state.BuilderData.GetNextState(conflict);
                var reduceItems = state.BuilderData.ReduceItems.SelectByLookahead(conflict).ToList();
                if (newState == null || reduceItems.Count != 1)
                {
                    continue; // this cannot be fixed by precedence
                }
                state.Actions[conflict] = new PrecedenceBasedParserAction(conflict, newState, reduceItems[0].Core.Production);
                allConflicts.Remove(conflict);
            } //foreach conflict
        }
Пример #2
0
        public void AddItem(LR0Item core)
        {
            //Check if a core had been already added. If yes, simply return
            if (!_allCores.Add(core))
            {
                return;
            }
            //Create new item, add it to AllItems, InitialItems, ReduceItems or ShiftItems
            var item = new LRItem(_state, core);

            AllItems.Add(item);

            if (item.Core.IsFinal)
            {
                ReduceItems.Add(item);
            }
            else
            {
                ShiftItems.Add(item);
            }

            if (item.Core.IsInitial)
            {
                InitialItems.Add(item);
            }

            if (core.IsFinal)
            {
                return;
            }

            //Add current term to ShiftTerms
            if (!ShiftTerms.Add(core.Current))
            {
                return;
            }

            if (core.Current is Terminal)
            {
                ShiftTerminals.Add(core.Current as Terminal);
            }

            //If current term (core.Current) is a new non-terminal, expand it
            var currNt = core.Current as NonTerminal;

            if (currNt == null)
            {
                return;
            }

            foreach (var prod in currNt.Productions)
            {
                AddItem(prod.LR0Items[0]);
            }
        }
Пример #3
0
        public override void Apply(LanguageData language, LRItem owner)
        {
            var state     = owner.State;
            var conflicts = state.BuilderData.Conflicts;

            if (conflicts.Count == 0)
            {
                return;
            }
            switch (ActionType)
            {
            case PreferredActionType.Shift:
                var currTerm = owner.Core.Current as Terminal;
                if (currTerm == null || !conflicts.Contains(currTerm))
                {
                    return;                                              //nothing to do
                }
                //Current term for shift item (hint owner) is a conflict - resolve it with shift action
                var newState    = owner.ShiftedItem.State;
                var shiftAction = new ShiftParserAction(owner);
                state.Actions[currTerm] = shiftAction;
                conflicts.Remove(currTerm);
                return;

            case PreferredActionType.Reduce:
                if (!owner.Core.IsFinal)
                {
                    return;                //we take care of reduce items only here
                }
                //we have a reduce item with "Reduce" hint. Check if any of lookaheads are in conflict
                ReduceParserAction reduceAction = null;
                foreach (var lkhead in owner.Lookaheads)
                {
                    if (conflicts.Contains(lkhead))
                    {
                        if (reduceAction == null)
                        {
                            reduceAction = new ReduceParserAction(owner.Core.Production);
                        }
                        state.Actions[lkhead] = reduceAction;
                        conflicts.Remove(lkhead);
                    }
                }
                return;
            } //switch
        }     //method
Пример #4
0
 /// <summary> Gives a chance to a custom code in hint to interfere in parser automaton construction.</summary>
 /// <param name="language">The LanguageData instance.</param>
 /// <param name="owner">The LRItem that "owns" the hint. </param>
 /// <remarks>
 /// The most common purpose of this method (it's overrides) is to resolve the conflicts
 /// by adding specific actions into State.Actions dictionary.
 /// The owner parameter represents the position in the grammar expression where the hint
 /// is found. The parser state is available through owner.State property.
 /// </remarks>
 public virtual void Apply(LanguageData language, LRItem owner)
 {
     // owner.State  -- the parser state
     // owner.State.BuilderData.Conflicts -- as set of conflict terminals
     // owner.State.Actions -- a dictionary of actions in the current state.
 }