private void PropagateLookaheads() { LRItemList currentList = new LRItemList(); //first collect all items foreach (ParserState state in Data.States) { currentList.AddRange(state.Items); } //Main loop - propagate until done while (currentList.Count > 0) { LRItemList newList = new LRItemList(); foreach (LRItem item in currentList) { if (item.NewLookaheads.Count == 0) { continue; } int oldCount = item.Lookaheads.Count; item.Lookaheads.AddRange(item.NewLookaheads); if (item.Lookaheads.Count != oldCount) { foreach (LRItem targetItem in item.PropagateTargets) { targetItem.NewLookaheads.AddRange(item.NewLookaheads); newList.Add(targetItem); } //foreach targetItem } //if item.NewLookaheads.Clear(); } //foreach item currentList = newList; } //while } //method
private void PropagateLookaheads() { LRItemList currentList = new LRItemList(); _data.States.ForEach(state => currentList.AddRange(state.Items)); while (currentList.Count > 0) { LRItemList newList = new LRItemList(); foreach (LRItem item in currentList) { if (item.NewLookaheads.Count == 0) { continue; } int oldCount = item.Lookaheads.Count; item.Lookaheads.AddRange(item.NewLookaheads); if (item.Lookaheads.Count != oldCount) { foreach (LRItem targetItem in item.PropagateTargets) { targetItem.NewLookaheads.AddRange(item.NewLookaheads); newList.Add(targetItem); } } item.NewLookaheads.Clear(); } currentList = newList; } }
public ParserState(string name, LR0ItemList coreItems) { Name = name; foreach (LR0Item coreItem in coreItems) { Items.Add(new LRItem(this, coreItem)); } }
private bool TryResolveConflictByHints(ParserState state, BnfTerm conflict) { var stateData = state.BuilderData; //reduce hints var reduceItems = stateData.ReduceItems.SelectByLookahead(conflict); foreach(var reduceItem in reduceItems) if (reduceItem.Core.Hints != null) foreach (var hint in reduceItem.Core.Hints) if (hint.HintType == HintType.ResolveToReduce) { var newAction = ParserAction.CreateReduce(reduceItem.Core.Production); state.Actions[conflict] = newAction; //replace/add reduce action return true; } //Shift hints var shiftItems = stateData.ShiftItems.SelectByCurrent(conflict); foreach (var shiftItem in shiftItems) if (shiftItem.Core.Hints != null) foreach (var hint in shiftItem.Core.Hints) if (hint.HintType == HintType.ResolveToShift) { //shift action is already there return true; } //code hints // first prepare data for conflict action: reduceProduction (for possible reduce) and newState (for possible shift) var reduceProduction = reduceItems.First().Core.Production; //take first of reduce productions ParserState newState = (state.Actions.ContainsKey(conflict) ? state.Actions[conflict].NewState : null); // Get all items that might contain hints; first take all shift items and reduce items in conflict; // we should also add lookahead sources of reduce items. Lookahead source is an LR item that produces the lookahead, // so if it contains a code hint right before the lookahead term, then it applies to this conflict as well. var allItems = new LRItemList(); allItems.AddRange(shiftItems); foreach (var reduceItem in reduceItems) { allItems.Add(reduceItem); allItems.AddRange(reduceItem.ReducedLookaheadSources); } // Scan all items and try to find hint with resolution type Code foreach (var item in allItems) if (item.Core.Hints != null) foreach (var hint in item.Core.Hints) if (hint.HintType == HintType.ResolveInCode) { //found hint with resolution type "code" - this is instruction to use custom code here to resolve the conflict // create new ConflictAction and place it into Actions table var newAction = ParserAction.CreateCodeAction(newState, reduceProduction); state.Actions[conflict] = newAction; //replace/add reduce action return true; } return false; }
private bool TryResolveConflictByHints(ParserState state, BnfTerm conflict) { var stateData = state.BuilderData; //reduce hints var reduceItems = stateData.ReduceItems.SelectByLookahead(conflict); foreach (var reduceItem in reduceItems) { if (reduceItem.Core.Hints != null) { foreach (var hint in reduceItem.Core.Hints) { if (hint.HintType == HintType.ResolveToReduce) { var newAction = ParserAction.CreateReduce(reduceItem.Core.Production); state.Actions[conflict] = newAction; //replace/add reduce action return(true); } } } } //Shift hints var shiftItems = stateData.ShiftItems.SelectByCurrent(conflict); foreach (var shiftItem in shiftItems) { if (shiftItem.Core.Hints != null) { foreach (var hint in shiftItem.Core.Hints) { if (hint.HintType == HintType.ResolveToShift) { //shift action is already there return(true); } } } } //code hints // first prepare data for conflict action: reduceProduction (for possible reduce) and newState (for possible shift) var reduceProduction = reduceItems.First().Core.Production; //take first of reduce productions ParserState newState = (state.Actions.ContainsKey(conflict) ? state.Actions[conflict].NewState : null); // Get all items that might contain hints; first take all shift items and reduce items in conflict; // we should also add lookahead sources of reduce items. Lookahead source is an LR item that produces the lookahead, // so if it contains a code hint right before the lookahead term, then it applies to this conflict as well. var allItems = new LRItemList(); allItems.AddRange(shiftItems); foreach (var reduceItem in reduceItems) { allItems.Add(reduceItem); allItems.AddRange(reduceItem.ReducedLookaheadSources); } // Scan all items and try to find hint with resolution type Code foreach (var item in allItems) { if (item.Core.Hints != null) { foreach (var hint in item.Core.Hints) { if (hint.HintType == HintType.ResolveInCode) { //found hint with resolution type "code" - this is instruction to use custom code here to resolve the conflict // create new ConflictAction and place it into Actions table var newAction = ParserAction.CreateCodeAction(newState, reduceProduction); state.Actions[conflict] = newAction; //replace/add reduce action return(true); } } } } return(false); }
private void PropagateLookaheads() { LRItemList currentList = new LRItemList(); _data.States.ForEach(state => currentList.AddRange(state.Items)); while (currentList.Count > 0) { LRItemList newList = new LRItemList(); foreach (LRItem item in currentList) { if (item.NewLookaheads.Count == 0) continue; int oldCount = item.Lookaheads.Count; item.Lookaheads.AddRange(item.NewLookaheads); if (item.Lookaheads.Count != oldCount) { foreach (LRItem targetItem in item.PropagateTargets) { targetItem.NewLookaheads.AddRange(item.NewLookaheads); newList.Add(targetItem); } } item.NewLookaheads.Clear(); } currentList = newList; } }
public ParserState(string name, LRItem item) { Name = name; Items.Add(item); }