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); }
}//method /* Detecting conflicts that cannot be resolved by tail wrapping * 1. Shift-reduce conflicts. If inadequate state S has shift item based on the same core as source * of one of reduced lookaheads of reduce item, then the conflict is unresolvable - * no wrapping of lookahead would resolve ambiguity * 2. Reduce-reduce conflict. If reduce items in inadequate state have reduced lookaheads * with sources having the same core (LR0 item) then we have unresolvable conflict. Wrapping of the item tail would produce * the same new non-terminal as lookahead in both conflicting reduce items. */ private void DetectConflictsUnresolvableByRestructuring(ParserState state) { //compute R-R and S-R conflicting lookaheads var rrConflicts = new BnfTermSet(); var srConflicts = new BnfTermSet(); var conflictSources = new LR0ItemSet(); foreach (var conflict in state.BuilderData.Conflicts) { var nonConflictingSourceCores = new LR0ItemSet(); foreach (var reduceItem in state.BuilderData.ReduceItems) { foreach (var source in reduceItem.ReducedLookaheadSources) { if (source.Core.Current != conflict) { continue; } if (state.BuilderData.Cores.Contains(source.Core)) //we have unresolvable shift-reduce { srConflicts.Add(source.Core.Current); conflictSources.Add(source.Core); } else if (nonConflictingSourceCores.Contains(source.Core)) //unresolvable reduce-reduce { rrConflicts.Add(source.Core.Current); conflictSources.Add(source.Core); } else { nonConflictingSourceCores.Add(source.Core); } } //foreach source } //foreach item } //foreach conflict if (srConflicts.Count > 0) { ReportParseConflicts("Ambiguous grammar, unresolvable shift-reduce conflicts.", state, srConflicts); } if (rrConflicts.Count > 0) { ReportParseConflicts("Ambiguous grammar, unresolvable reduce-reduce conflicts.", state, rrConflicts); } //create default actions and remove them from conflict list, so we don't deal with them anymore CreateDefaultActionsForConflicts(state, srConflicts, rrConflicts); } // method
}//method /* Detecting conflicts that cannot be resolved by tail wrapping 1. Shift-reduce conflicts. If inadequate state S has shift item based on the same core as source of one of reduced lookaheads of reduce item, then the conflict is unresolvable - no wrapping of lookahead would resolve ambiguity 2. Reduce-reduce conflict. If reduce items in inadequate state have reduced lookaheads with sources having the same core (LR0 item) then we have unresolvable conflict. Wrapping of the item tail would produce the same new non-terminal as lookahead in both conflicting reduce items. */ private void DetectConflictsUnresolvableByRestructuring(ParserState state) { //compute R-R and S-R conflicting lookaheads var rrConflicts = new BnfTermSet(); var srConflicts = new BnfTermSet(); var conflictSources = new LR0ItemSet(); foreach (var conflict in state.BuilderData.Conflicts) { var nonConflictingSourceCores = new LR0ItemSet(); foreach (var reduceItem in state.BuilderData.ReduceItems) { foreach (var source in reduceItem.ReducedLookaheadSources) { if (source.Core.Current != conflict) continue; if (state.BuilderData.Cores.Contains(source.Core)) { //we have unresolvable shift-reduce srConflicts.Add(source.Core.Current); conflictSources.Add(source.Core); } else if (nonConflictingSourceCores.Contains(source.Core)) { //unresolvable reduce-reduce rrConflicts.Add(source.Core.Current); conflictSources.Add(source.Core); } else nonConflictingSourceCores.Add(source.Core); }//foreach source }//foreach item }//foreach conflict if (srConflicts.Count > 0) ReportParseConflicts("Ambiguous grammar, unresolvable shift-reduce conflicts.", state, srConflicts); if (rrConflicts.Count > 0) ReportParseConflicts("Ambiguous grammar, unresolvable reduce-reduce conflicts.", state, rrConflicts); //create default actions and remove them from conflict list, so we don't deal with them anymore CreateDefaultActionsForConflicts(state, srConflicts, rrConflicts); } // 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; }
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; }