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
public PrecedenceBasedParserAction(BnfTerm shiftTerm, ParserState newShiftState, Production reduceProduction) { _reduceAction = new ReduceParserAction(reduceProduction); var reduceEntry = new ConditionalEntry(CheckMustReduce, _reduceAction, "(Precedence comparison)"); base.ConditionalEntries.Add(reduceEntry); base.DefaultAction = _shiftAction = new ShiftParserAction(shiftTerm, newShiftState); }
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
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
public CustomParserAction(LanguageData language, ParserState state, ExecuteActionMethod executeRef) { Language = language; State = state; ExecuteRef = 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)); } }
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; } } //method
//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 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); }