public void Add() { State state = new State(); Item item = new Item(new Production(), state); state.Add(item); Assert.AreEqual(1, state.Count); }
private Item(Production production, int index, State parent, Item prevItem) { if (production == null || parent == null) { throw new ArgumentNullException(); } if (index < 0 || index > production.Symbols.Count) { throw new ArgumentOutOfRangeException(); } if (index == 0 && prevItem != null) { throw new ArgumentException(); } if (index > 0 && prevItem == null) { throw new ArgumentNullException(); } this.production = production; this.index = index; this.parent = parent; this.prevItem = prevItem; this.derivations = index == 0 ? null : new List<object>(); }
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 Contains() { State s = new State(); Item item = new Item(new Production(), s); Assert.IsFalse(s.Contains(item)); s.Add(item); Assert.IsTrue(s.Contains(item)); }
public void AddDuplicate() { State state = new State(); Production p = new Production(new Terminal('x', 'y')); Item itemA = new Item(p, state); itemA.Add('x'); state.Add(itemA); Item itemB = new Item(p, state); itemB.Add('y'); state.Add(itemB); }
public void Enumerate() { State state = new State(); Item item = new Item(new Production(), state); state.Add(item); Assert.AreEqual(item, state[0]); for (int i = 0; i < state.Count; i++) { item = state[i]; } }
public void GetItems() { State state = new State(); Nonterminal nt = new Nonterminal(); Production p = new Production(nt); nt.Add(p); Item item = new Item(p, state); state.Add(item); state.Add(new Item(new Production(), state)); IList<Item> items = state.GetItems(p); Assert.AreEqual(1, items.Count); Assert.AreSame(item, items[0]); }
public void Equals() { Production p = new Production(Terminal.Eof); State s = new State(); Item item = new Item(p, s); Assert.IsFalse(item.Equals(null)); Assert.IsFalse(item.Equals(new object())); Assert.IsTrue(item.Equals(item), "Identity"); Assert.IsTrue(item.Equals(new Item(p, s)), "Value equality"); Assert.IsFalse(item.Equals(new Item(p, new State())), "Vary by state"); Assert.IsFalse(item.Equals(new Item(new Production(), s)), "Vary by production"); Assert.IsFalse(item.Equals(item.NextItem), "Vary by index"); Item another = new Item(p, s); Assert.IsFalse(item.NextItem.Equals(another.NextItem), "Vary by previous item"); }
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); }
internal Item(Production production, State parent) : this(production, 0, parent, null) { }
public void Create() { State state = new State(); }
private void Predictor( State state, Item item, IDictionary<Production,IList<Item>> completedNullable) { Debug.Assert(!item.AtEnd && item.Symbol is Nonterminal); Nonterminal nt = item.Symbol as Nonterminal; foreach (Production p in nt.Productions) { Item newItem = new Item(p, state); if (!state.Contains(newItem)) { state.Add(newItem); ShiftCompletedNullable(state, newItem, completedNullable); } } }
private void Scanner(Item item, State next, int ch) { Debug.Assert(!item.AtEnd && item.Symbol is Terminal); Terminal t = item.Symbol as Terminal; if (t.Contains(ch)) { Item newItem = item.NextItem; newItem.Add(ch); next.Add(newItem); } }
public void ItemPastEnd() { Item item = new State()[0]; }
public void ItemNegativeIndex() { Item item = new State()[-1]; }
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); }
private IList<object> Parse(TextReader input) { if (input == null) throw new ArgumentNullException(); State initial = new State(); initial.Add(new Item(startProduction, initial)); State current = initial; State next = new State(); do { IDictionary<Production, IList<Item>> completedNullable = new Dictionary<Production, IList<Item>>(); for (int i = 0; i < current.Count; i++) { Item item = current[i]; if (!item.AtEnd && item.Symbol is Nonterminal) { Predictor(current, item, completedNullable); } else if (!item.AtEnd && item.Symbol is Terminal) { Scanner(item, next, input.Peek()); } else { Completer(current, item, completedNullable); } } current = next; next = new State(); } while (input.Read() != -1 && current.Count > 0); if (current.Count == 1 && current[0].AtEnd && current[0].Production == startProduction && current[0].Parent == initial) { return current[0].Reduce(); } else { return new List<object>(); } }
// 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); } } }