Beispiel #1
0
        //Check if there is an action already in state for this term; if yes, and it is Conditional action,
        // then simply add an extra conditional entry to it. If an action does not exist, or it is not conditional,
        // create new conditional action for this term.
        private void AddConditionalEntry(ParserState state, BnfTerm term, ConditionalParserAction.ConditionalEntry entry)
        {
            ConditionalParserAction condAction = null;

            if (state.Actions.TryGetValue(term, out ParserAction oldAction))
            {
                condAction = oldAction as ConditionalParserAction;
            }
            if (condAction == null)   //there's no old action, or it is not conditional; create new conditional action
            {
                condAction = new ConditionalParserAction {
                    DefaultAction = oldAction
                };
                state.Actions[term] = condAction;
            }
            condAction.ConditionalEntries.Add(entry);
            if (condAction.DefaultAction == null)
            {
                condAction.DefaultAction = FindDefaultAction(state, term);
            }
            if (condAction.DefaultAction == null)
            {
                //if still no action, then use the cond. action as default.
                condAction.DefaultAction = entry.Action;
            }
        }
Beispiel #2
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();
            }
        }