private void ComputeLookaheads(LRItemSet forItems) { foreach (var reduceItem in forItems) { // Find all source states - those that contribute lookaheads var sourceStates = new ParserStateSet(); foreach (var lookbackTrans in reduceItem.Lookbacks) { sourceStates.Add(lookbackTrans.ToState); sourceStates.UnionWith(lookbackTrans.ToState.BuilderData.ReadStateSet); foreach (var includeTrans in lookbackTrans.Includes) { sourceStates.Add(includeTrans.ToState); sourceStates.UnionWith(includeTrans.ToState.BuilderData.ReadStateSet); } //foreach includeTrans } //foreach lookbackTrans //Now merge all shift terminals from all source states foreach (var state in sourceStates) { reduceItem.Lookaheads.UnionWith(state.BuilderData.ShiftTerminals); } //Remove SyntaxError - it is pseudo terminal if (reduceItem.Lookaheads.Contains(_grammar.SyntaxError)) { reduceItem.Lookaheads.Remove(_grammar.SyntaxError); } //Sanity check if (reduceItem.Lookaheads.Count == 0) { _language.Errors.Add(GrammarErrorLevel.InternalError, reduceItem.State, "Reduce item '{0}' in state {1} has no lookaheads.", reduceItem.Core, reduceItem.State); } } //foreach reduceItem } //method
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); }
//We compute only transitions that are really needed to compute lookaheads in inadequate states. // We start with reduce items in inadequate state and find their lookbacks - this is initial list of transitions. // Then for each transition in the list we check if it has items with nullable tails; for those items we compute // lookbacks - these are new or already existing transitons - and so on, we repeat the operation until no new transitions // are created. private void ComputeTransitions(LRItemSet forItems) { var newItemsNeedLookbacks = forItems; while (newItemsNeedLookbacks.Count > 0) { var newTransitions = CreateLookbackTransitions(newItemsNeedLookbacks); newItemsNeedLookbacks = SelectNewItemsThatNeedLookback(newTransitions); } }
//We compute only transitions that are really needed to compute lookaheads in inadequate states. // We start with reduce items in inadequate state and find their lookbacks - this is initial list of transitions. // Then for each transition in the list we check if it has items with nullable tails; for those items we compute // lookbacks - these are new or already existing transitons - and so on, we repeat the operation until no new transitions // are created. private void ComputeTransitions() { var newItemsNeedLookbacks = _itemsNeedLookaheads = GetReduceItemsInInadequateState(); while (newItemsNeedLookbacks.Count > 0) { var newTransitions = CreateLookbackTransitions(newItemsNeedLookbacks); newItemsNeedLookbacks = SelectNewItemsThatNeedLookback(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); }
public LRItemSet SelectByLookahead(Terminal lookahead) { var result = new LRItemSet(); foreach (var item in this) { if (item.Lookaheads.Contains(lookahead)) { result.Add(item); } } return(result); }
public LRItemSet SelectByCurrent(BnfTerm current) { var result = new LRItemSet(); foreach (var item in this) { if (item.Core.Current == current) { result.Add(item); } } return(result); }
public Transition(ParserState fromState, NonTerminal overNonTerminal) { FromState = fromState; OverNonTerminal = overNonTerminal; ToState = FromState.Actions[overNonTerminal].NewState; _hashCode = unchecked (FromState.GetHashCode() - overNonTerminal.GetHashCode()); FromState.BuilderData.Transitions.Add(overNonTerminal, this); Items = FromState.BuilderData.ShiftItems.SelectByCurrent(overNonTerminal); foreach (var item in Items) { item.Transition = this; } }//constructor
private LRItemSet GetReduceItemsInInadequateState() { var result = new LRItemSet(); foreach (var state in _data.States) { if (state.BuilderData.IsInadequate) { result.UnionWith(state.BuilderData.ReduceItems); } } return(result); }
public LRItemSet SelectItemsWithNullableTails() { var result = new LRItemSet(); foreach (var item in this) { if (item.Core.TailIsNullable) { result.Add(item); } } return(result); }
private LRItemSet SelectNewItemsThatNeedLookback(TransitionList transitions) { //Select items with nullable tails that don't have lookbacks yet var items = new LRItemSet(); foreach (var trans in transitions) { foreach (var item in trans.Items) { if (item.Core.TailIsNullable && item.Lookbacks.Count == 0) //only if it does not have lookbacks yet { items.Add(item); } } } return(items); }