//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 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)); } }
//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); }