예제 #1
0
        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));
        }
예제 #2
0
        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));
        }
예제 #3
0
        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
예제 #4
0
        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);
        }
예제 #5
0
        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);
        }
예제 #6
0
        /// <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);
                    }
                }
            }
        }
예제 #7
0
 /// <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);
 }