Ejemplo n.º 1
0
        public override void Apply(LanguageData language, Construction.LRItem owner)
        {
            //Create custom action and put it into state.Actions table
            var state  = owner.State;
            var action = new CustomParserAction(language, state, _executeMethod);

            if (_previewMethod != null)
            {
                _previewMethod(action);
            }
            if (!state.BuilderData.IsInadequate) // adequate state, with a single possible action which is DefaultAction
            {
                state.DefaultAction = action;
            }
            else if (owner.Core.Current != null) //shift action
            {
                state.Actions[owner.Core.Current] = action;
            }
            else
            {
                foreach (var lkh in owner.Lookaheads)
                {
                    state.Actions[lkh] = action;
                }
            }
            //We consider all conflicts handled by the action
            state.BuilderData.Conflicts.Clear();
        } //method
Ejemplo n.º 2
0
        public override void Apply(LanguageData language, Construction.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 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 head 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 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 ConditionalEntry(CheckCondition, shiftAction, _description);
                AddConditionalEntry(state, curr, shiftCondEntry);
                if (conflicts.Contains(curr))
                {
                    conflicts.Remove(curr);
                }
                break;
            }
        }//method
Ejemplo n.º 3
0
        public override void Apply(LanguageData language, Construction.LRItem owner)
        {
            //Check that owner is not final - we can imply precedence only in shift context
            var curr = owner.Core.Current;

            if (curr == null)
            {
                return;
            }
            //mark the state, to make sure we do stuff in Term_Shifting event handler only in appropriate states
            owner.State.CustomFlags |= ImpliedPrecedenceCustomFlag;
            curr.Shifting           += Term_Shifting;
        }
Ejemplo n.º 4
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]);
            }
        }//method
Ejemplo n.º 5
0
 public ShiftParserAction(Construction.LRItem item) : this(item.Core.Current, item.ShiftedItem.State)
 {
 }
Ejemplo n.º 6
0
        }         //method

        private void ResolveConflictByHints(ParserState state, Terminal conflict)
        {
            var stateData = state.BuilderData;

            //reduce hints
            var reduceItems = stateData.ReduceItems.SelectByLookahead(conflict);

            foreach (var reduceItem in reduceItems)
            {
                if (reduceItem.Core.Hints.Find(h => h.HintType == HintType.ResolveToReduce) != null)
                {
                    state.Actions[conflict] = new ParserAction(ParserActionType.Reduce, null, reduceItem.Core.Production);
                    state.BuilderData.ResolvedConflicts.Add(conflict);
                    return;
                }
            }

            //shift hints
            var shiftItems = stateData.ShiftItems.SelectByCurrent(conflict);

            foreach (var shiftItem in shiftItems)
            {
                if (shiftItem.Core.Hints.Find(h => h.HintType == HintType.ResolveToShift) != null)
                {
                    //shift action is already there
                    state.BuilderData.ResolvedConflicts.Add(conflict);
                    return;
                }
            }

            //code hints
            // first prepare data for conflict action: reduceProduction (for possible reduce) and newState (for possible shift)
            var         reduceProduction = reduceItems.First().Core.Production; //take first of reduce productions
            ParserState newState         = (state.Actions.ContainsKey(conflict) ? state.Actions[conflict].NewState : null);
            // Get all items that might contain hints;
            var allItems = new LRItemList();

            allItems.AddRange(state.BuilderData.ShiftItems.SelectByCurrent(conflict));
            allItems.AddRange(state.BuilderData.ReduceItems.SelectByLookahead(conflict));
            // Scan all items and try to find hint with resolution type Code
            foreach (var item in allItems)
            {
                if (item.Core.Hints.Find(h => h.HintType == HintType.ResolveInCode) != null)
                {
                    state.Actions[conflict] = new ParserAction(ParserActionType.Code, newState, reduceProduction);
                    state.BuilderData.ResolvedConflicts.Add(conflict);
                    return;
                }
            }

            //custom hints
            // find custom grammar hints and build custom conflict resolver
            var    customHints = new List <CustomGrammarHint>();
            var    hintItems   = new Dictionary <CustomGrammarHint, LRItem>();
            LRItem defaultItem = null; // the first item with no hints

            foreach (var item in allItems)
            {
                var hints = item.Core.Hints.OfType <CustomGrammarHint>();
                foreach (var hint in hints)
                {
                    customHints.Add(hint);
                    hintItems[hint] = item;
                }
                if (defaultItem == null && !hints.Any())
                {
                    defaultItem = item;
                }
            }
            // if there are custom hints, build conflict resolver
            if (customHints.Count > 0)
            {
                state.Actions[conflict] = new ParserAction(newState, reduceProduction, args => {
                    // examine all custom hints and select the first production that matched
                    foreach (var customHint in customHints)
                    {
                        if (customHint.Match(args))
                        {
                            var item = hintItems[customHint];
                            args.ReduceProduction = item.Core.Production;
                            args.Result           = customHint.Action;
                            return;
                        }
                    }
                    // no hints matched, select default LRItem
                    if (defaultItem != null)
                    {
                        args.ReduceProduction = defaultItem.Core.Production;
                        args.Result           = args.NewShiftState != null ? ParserActionType.Shift : ParserActionType.Reduce;
                        return;
                    }
                    // prefer Reduce if Shift operation is not available
                    args.Result = args.NewShiftState != null ? ParserActionType.Shift : ParserActionType.Reduce;
                    // TODO: figure out what to do next
                });
                state.BuilderData.ResolvedConflicts.Add(conflict);
                return;
            }
        }