private void Completer( State state, Item item, IDictionary<Production,IList<Item>> completedNullable) { Debug.Assert(item.AtEnd); if (item.Parent == state) { // completed a nullable item if (!completedNullable.ContainsKey(item.Production)) { completedNullable[item.Production] = new List<Item>(); } completedNullable[item.Production].Add(item); } foreach (Item parentItem in item.Parent.GetItems(item.Production)) { Item newItem = state.Import(parentItem.NextItem); newItem.Add(item); ShiftCompletedNullable(state, newItem, completedNullable); } }
public void ImportIncompatible() { Production p = new Production(new Terminal('a', 'b')); Item item = new Item(p, new State()); State s = new State(); Item next = item.NextItem; next.Add('a'); s.Add(next); Item newNext = item.NextItem; newNext.Add('b'); s.Import(newNext); }
public void Import() { Production p = new Production(new Terminal('a', 'b')); Item item = new Item(p, new State()); State s = new State(); Item next = item.NextItem; next.Add('a'); s.Add(next); Item imported = s.Import(item.NextItem); Assert.AreSame(next, imported); item = new Item(new Production(), new State()); imported = s.Import(item); Assert.AreSame(item, imported); }
// When an item is added to the current state, any nullable // productions that have already been completed need to be // added to the new item private void ShiftCompletedNullable( State state, Item item, IDictionary<Production, IList<Item>> completedNullable) { if (!item.AtEnd && item.Symbol is Nonterminal) { Item nextItem = null; foreach (Production p in completedNullable.Keys) { if (((Nonterminal)item.Symbol).Contains(p)) { if (nextItem == null) { nextItem = state.Import(item.NextItem); } foreach (Item nullableItem in completedNullable[p]) { nextItem.Add(nullableItem); } } } if (nextItem != null) { ShiftCompletedNullable(state, nextItem, completedNullable); } } }