Esempio n. 1
0
 //Create reduce actions for states with a single reduce item (and no shifts)
 private void CreateRemainingReduceActions()
 {
     foreach (var state in _data.States)
     {
         if (state.DefaultAction != null)
         {
             continue;
         }
         var stateData = state.BuilderData;
         if (stateData.ShiftItems.Count == 0 && stateData.ReduceItems.Count == 1)
         {
             state.DefaultAction = ReduceParserAction.Create(stateData.ReduceItems.First().Core.Production);
             continue; //next state; if we have default reduce action, we don't need to fill actions dictionary for lookaheads
         }
         //create actions
         foreach (var item in state.BuilderData.ReduceItems)
         {
             var action = ReduceParserAction.Create(item.Core.Production);
             foreach (var lkh in item.Lookaheads)
             {
                 if (state.Actions.ContainsKey(lkh))
                 {
                     continue;
                 }
                 state.Actions[lkh] = action;
             }
         } //foreach item
     }     //foreach state
 }
 public PrecedenceBasedParserAction(BnfTerm shiftTerm, ParserState newShiftState, Production reduceProduction)
 {
     _reduceAction = new ReduceParserAction(reduceProduction);
     var reduceEntry = new ConditionalEntry(CheckMustReduce, _reduceAction, "(Precedence comparison)");
     ConditionalEntries.Add(reduceEntry);
     DefaultAction = _shiftAction = new ShiftParserAction(shiftTerm, newShiftState);
 }
Esempio n. 3
0
        }     //method

        //Resolve to default actions
        private void HandleUnresolvedConflicts()
        {
            foreach (var state in _data.States)
            {
                if (state.BuilderData.Conflicts.Count == 0)
                {
                    continue;
                }
                var shiftReduceConflicts  = state.BuilderData.GetShiftReduceConflicts();
                var reduceReduceConflicts = state.BuilderData.GetReduceReduceConflicts();
                var stateData             = state.BuilderData;
                if (shiftReduceConflicts.Count > 0)
                {
                    _language.Errors.Add(GrammarErrorLevel.Conflict, state, Resources.ErrSRConflict, state, shiftReduceConflicts.ToString());
                }
                if (reduceReduceConflicts.Count > 0)
                {
                    _language.Errors.Add(GrammarErrorLevel.Conflict, state, Resources.ErrRRConflict, state, reduceReduceConflicts.ToString());
                }
                //Create default actions for these conflicts. For shift-reduce, default action is shift, and shift action already
                // exist for all shifts from the state, so we don't need to do anything, only report it
                //For reduce-reduce create reduce actions for the first reduce item (whatever comes first in the set).
                foreach (var conflict in reduceReduceConflicts)
                {
                    var reduceItems = stateData.ReduceItems.SelectByLookahead(conflict);
                    var firstProd   = reduceItems.First().Core.Production;
                    var action      = new ReduceParserAction(firstProd);
                    state.Actions[conflict] = action;
                }
                //stateData.Conflicts.Clear(); -- do not clear them, let the set keep the auto-resolved conflicts, may find more use for this later
            }
        }
Esempio n. 4
0
        public PrecedenceBasedParserAction(BnfTerm shiftTerm, ParserState newShiftState, Production reduceProduction)
        {
            _reduceAction = new ReduceParserAction(reduceProduction);
            var reduceEntry = new ConditionalEntry(CheckMustReduce, _reduceAction, "(Precedence comparison)");

            ConditionalEntries.Add(reduceEntry);
            DefaultAction = _shiftAction = new ShiftParserAction(shiftTerm, newShiftState);
        }
Esempio n. 5
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))
                {
                    //nothing to do
                    return;
                }
                //Current term for shift item (hint owner) is a conflict - resolve it with shift action
                var shiftAction = new ShiftParserAction(owner);
                state.Actions[currTerm] = shiftAction;
                conflicts.Remove(currTerm);
                return;

            case PreferredActionType.Reduce:
                if (!owner.Core.IsFinal)
                {
                    //we take care of reduce items only here
                    return;
                }
                //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;

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
Esempio n. 6
0
        public CustomParserAction(LanguageData language, ParserState state, ExecuteActionMethod executeRef)
        {
            Language   = language;
            State      = state;
            ExecuteRef = executeRef ?? throw new ArgumentNullException(nameof(executeRef));
            Conflicts.UnionWith(state.BuilderData.Conflicts);

            // Create default shift and reduce actions
            foreach (var shiftItem in state.BuilderData.ShiftItems)
            {
                ShiftActions.Add(new ShiftParserAction(shiftItem));
            }
            foreach (var item in state.BuilderData.ReduceItems)
            {
                ReduceActions.Add(ReduceParserAction.Create(item.Core.Production));
            }
        }
Esempio n. 7
0
        //Find an LR item without hints compatible with term (either shift on term or reduce with term as lookahead);
        // this item without hints would become our default. We assume that other items have hints, and when conditions
        // on all these hints fail, we chose this remaining item without hints.
        private static ParserAction FindDefaultAction(ParserState state, BnfTerm term)
        {
            //First check reduce items
            var reduceItems = state.BuilderData.ReduceItems.SelectByLookahead(term as Terminal);

            foreach (var item in reduceItems)
            {
                if (item.Core.Hints.Count == 0)
                {
                    return(ReduceParserAction.Create(item.Core.Production));
                }
            }
            var shiftItem = state.BuilderData.ShiftItems.SelectByCurrent(term).FirstOrDefault();

            if (shiftItem != null)
            {
                return(new ShiftParserAction(shiftItem));
            }
            //if everything failed, returned first reduce item
            return(null);
        }
Esempio n. 8
0
 //Resolve to default actions
 private void HandleUnresolvedConflicts()
 {
     foreach (var state in _data.States) {
     if (state.BuilderData.Conflicts.Count == 0)
       continue;
     var shiftReduceConflicts = state.BuilderData.GetShiftReduceConflicts();
     var reduceReduceConflicts = state.BuilderData.GetReduceReduceConflicts();
     var stateData = state.BuilderData;
     if (shiftReduceConflicts.Count > 0)
       _language.Errors.Add(GrammarErrorLevel.Conflict, state, Resources.ErrSRConflict, state, shiftReduceConflicts.ToString());
     if (reduceReduceConflicts.Count > 0)
       _language.Errors.Add(GrammarErrorLevel.Conflict, state, Resources.ErrRRConflict, state, reduceReduceConflicts.ToString());
     //Create default actions for these conflicts. For shift-reduce, default action is shift, and shift action already
     // exist for all shifts from the state, so we don't need to do anything, only report it
     //For reduce-reduce create reduce actions for the first reduce item (whatever comes first in the set).
     foreach (var conflict in reduceReduceConflicts) {
       var reduceItems = stateData.ReduceItems.SelectByLookahead(conflict);
       var firstProd = reduceItems.First().Core.Production;
       var action = new ReduceParserAction(firstProd);
       state.Actions[conflict] = action;
     }
     //stateData.Conflicts.Clear(); -- do not clear them, let the set keep the auto-resolved conflicts, may find more use for this later
       }
 }
Esempio n. 9
0
        public override void Apply(LanguageData language, LRItem owner)
        {
            var state = owner.State;

            if (!state.BuilderData.IsInadequate)
            {
                return;                                  //the state is adequate, we don't need to do anything
            }
            var conflicts = state.BuilderData.Conflicts;

            // Note that we remove lookaheads from the state conflicts set at the end of this method - to let parser builder know
            // that this conflict is taken care of.
            // On the other hand we may call this method multiple times for different LRItems if we have multiple hints in the same state.
            // Since we remove lookahead from conflicts on the first call, on the consequitive calls it will not be a conflict -
            // but we still need to add a new conditional entry to a conditional parser action for this lookahead.
            // Thus we process the lookahead anyway, even if it is not a conflict.
            // if (conflicts.Count == 0) return; -- this is a wrong thing to do
            switch (_actionType)
            {
            case PreferredActionType.Reduce:
                if (!owner.Core.IsFinal)
                {
                    return;
                }
                //it is reduce action; find lookaheads in conflict
                var lkhs = owner.Lookaheads;
                if (lkhs.Count == 0)
                {
                    return;     //if no conflicts then nothing to do
                }
                var reduceAction    = new ReduceParserAction(owner.Core.Production);
                var reduceCondEntry = new ConditionalParserAction.ConditionalEntry(CheckCondition, reduceAction, _description);
                foreach (var lkh in lkhs)
                {
                    AddConditionalEntry(state, lkh, reduceCondEntry);
                    if (conflicts.Contains(lkh))
                    {
                        conflicts.Remove(lkh);
                    }
                }
                break;

            case PreferredActionType.Shift:
                var curr = owner.Core.Current as Terminal;
                if (curr == null)
                {
                    return;     //it is either reduce item, or curr is a NonTerminal - we cannot shift it
                }
                var shiftAction    = new ShiftParserAction(owner);
                var shiftCondEntry = new ConditionalParserAction.ConditionalEntry(CheckCondition, shiftAction, _description);
                AddConditionalEntry(state, curr, shiftCondEntry);
                if (conflicts.Contains(curr))
                {
                    conflicts.Remove(curr);
                }
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
        }