private TransitionList CreateLookbackTransitions(LRItemSet sourceItems) { var newTransitions = new TransitionList(); //Build set of initial cores - this is optimization for performance //We need to find all initial items in all states that shift into one of sourceItems // Each such initial item would have the core from the "initial" cores set that we build from source items. var iniCores = new LR0ItemSet(); foreach (var sourceItem in sourceItems) { iniCores.Add(sourceItem.Core.Production.LR0Items[0]); } //find foreach (var state in _data.States) { foreach (var iniItem in state.BuilderData.InitialItems) { if (!iniCores.Contains(iniItem.Core)) { continue; } var iniItemNt = iniItem.Core.Production.LValue; // iniItem's non-terminal (left side of production) Transition lookback = null; // local var for lookback - transition over iniItemNt var currItem = iniItem; // iniItem is initial item for all currItem's in the shift chain. while (currItem != null) { if (sourceItems.Contains(currItem)) { // We create transitions lazily, only when we actually need them. Check if we have iniItem's transition // in local variable; if not, get it from state's transitions table; if not found, create it. if (lookback == null && !state.BuilderData.Transitions.TryGetValue(iniItemNt, out lookback)) { lookback = new Transition(state, iniItemNt); newTransitions.Add(lookback); } //Now for currItem, either add trans to Lookbacks, or "include" it into currItem.Transition // We need lookbacks ONLY for final items; for non-Final items we need proper Include lists on transitions if (currItem.Core.IsFinal) { currItem.Lookbacks.Add(lookback); } else // if (currItem.Transition != null) // Note: looks like checking for currItem.Transition is redundant - currItem is either: // - Final - always the case for the first run of this method; // - it has a transition after the first run, due to the way we select sourceItems list // in SelectNewItemsThatNeedLookback (by transitions) { currItem.Transition.Include(lookback); } }//if //move to next item currItem = currItem.ShiftedItem; } //while } //foreach iniItem } //foreach state return(newTransitions); }
private TransitionList CreateLookbackTransitions(LRItemSet sourceItems) { var newTransitions = new TransitionList(); //Build set of initial cores - this is optimization for performance //We need to find all initial items in all states that shift into one of sourceItems // Each such initial item would have the core from the "initial" cores set that we build from source items. var iniCores = new LR0ItemSet(); foreach (var sourceItem in sourceItems) { iniCores.Add(sourceItem.Core.Production.LR0Items[0]); } //find foreach (var state in Data.States) { foreach (var iniItem in state.BuilderData.InitialItems) { if (!iniCores.Contains(iniItem.Core)) { continue; } var currItem = iniItem; while (currItem != null) { if (sourceItems.Contains(currItem)) { //iniItem is initial item for currItem (one of source items) // check if transition for iniItem's non-terminal exists var ntLeft = iniItem.Core.Production.LValue; Transition trans; if (!state.BuilderData.Transitions.TryGetValue(ntLeft, out trans)) { trans = new Transition(iniItem.State, iniItem.Core.Production.LValue); newTransitions.Add(trans); } //Now for currItem, either add trans to Lookbackbacks, or "include" it into currItem.Transition if (currItem.Core.IsFinal) { currItem.Lookbacks.Add(trans); } else if (currItem.Transition != null) { currItem.Transition.Include(trans); } }//if //move to next items currItem = currItem.ShiftedItem; } //while } //foreach iniItem } //foreach state return(newTransitions); }