public void Add_WhenTerminalIsAlreadyInSet_DoesNotAddDuplicate() { // Arrange: var ts = new TerminalSet(); const string terminal = "t"; // Act: ts.Add(terminal); ts.Add(terminal); // Assert: Assert.AreEqual(1, ts.AsEnumerable().Count()); Assert.IsTrue(ts.AsEnumerable().Contains(terminal)); }
public void Union_WhenIncludeEpsilon_ReturnsUnionOfSets(string[] set1, string[] set2, bool includeEpsilon, string[] expected) { // Arrange: var ts1 = new TerminalSet(); foreach (var terminal in set1) { ts1.Add(terminal); } var ts2 = new TerminalSet(); foreach (var terminal in set2) { ts2.Add(terminal); } ts2.Add(ts1.Epsilon); // Act: ts1.Union(ts2, includeEpsilon); // Assert: Assert.That(ts1.AsEnumerable(), Is.EquivalentTo(expected)); }
public void AddItem(LR0Item core) { //Check if a core had been already added. If yes, simply return if (!AllCores.Add(core)) { return; } //Create new item, add it to AllItems, InitialItems, ReduceItems or ShiftItems var item = new LRItem(State, core); AllItems.Add(item); if (item.Core.IsFinal) { ReduceItems.Add(item); } else { ShiftItems.Add(item); } if (item.Core.IsInitial) { InitialItems.Add(item); } if (core.IsFinal) { return; } //Add current term to ShiftTerms if (!ShiftTerms.Add(core.Current)) { return; } if (core.Current is Terminal) { ShiftTerminals.Add(core.Current as Terminal); } //If current term (core.Current) is a new non-terminal, expand it var currNt = core.Current as NonTerminal; if (currNt == null) { return; } foreach (var prod in currNt.Productions) { AddItem(prod.LR0Items[0]); } }//method
public void Includes_WhenTerminalsIncludeTestFor_ReturnsExpected(string[] terminals, string testFor, bool expected) { // Arrange: var ts = new TerminalSet(); foreach (var terminal in terminals) { ts.Add(terminal); } // Act: var actual = ts.Includes(testFor); // Assert: Assert.AreEqual(expected, actual); }
public void IsEmpty_WhenTerminalsHasValues_ReturnsExpected(string[] terminals, bool expected) { // Arrange: var ts = new TerminalSet(); foreach (var terminal in terminals) { ts.Add(terminal); } // Act: var actual = ts.IsEmpty(); // Assert: Assert.AreEqual(expected, actual); }
/// <summary> /// Closes this item to a set of items /// </summary> /// <param name="closure">The list to close</param> /// <param name="map">The current helper map</param> public override void CloseTo(List <Item> closure, Dictionary <Rule, Dictionary <int, List <Item> > > map) { // the item was of the form [Var -> alpha .] (reduction) // nothing to do if (Action == LRActionCode.Reduce) { return; } // Get the next symbol in the item Symbol next = GetNextSymbol(); // Here the item is of the form [Var -> alpha . Next beta] // If the next symbol is not a variable : do nothing // If the next symbol is a variable : Variable nextVar = next as Variable; if (nextVar == null) { return; } // Firsts is a copy of the Firsts set for beta (next choice) // Firsts will contains symbols that may follow Next // Firsts will therefore be the lookahead for child items TerminalSet firsts = new TerminalSet(GetNextChoice().Firsts); // If beta is nullifiable (contains ε) : if (firsts.Contains(Epsilon.Instance)) { // Remove ε firsts.Remove(Epsilon.Instance); // Add the item's lookahead as possible symbol for firsts firsts.Add(lookahead); } // For each rule that has Next as a head variable : foreach (Rule rule in nextVar.Rules) { if (!map.ContainsKey(rule)) { map.Add(rule, new Dictionary <int, List <Item> >()); } Dictionary <int, List <Item> > sub = map[rule]; if (!sub.ContainsKey(0)) { sub.Add(0, new List <Item>()); } List <Item> previouses = sub[0]; // For each symbol in Firsts : create the child with this symbol as lookahead foreach (Terminal first in firsts) { // Child item creation and unique insertion int sid = first.ID; bool found = false; foreach (Item previous in previouses) { if (previous.Lookaheads[0].ID == sid) { found = true; break; } } if (!found) { ItemLR1 New = new ItemLR1(rule, 0, first); closure.Add(New); previouses.Add(New); } } } }
/// <summary> /// Initializes this item /// </summary> /// <param name="rule">The underlying rule</param> /// <param name="position">The dot position in the rule</param> /// <param name="lookahead">The lookahead for this item</param> public ItemLR1(Rule rule, int position, Terminal lookahead) : base(rule, position) { this.lookahead = lookahead; lookaheads = new TerminalSet(); lookaheads.Add(lookahead); }