public NullableFirstTables(Grammar grammar)
        {
            this.grammar    = grammar;
            int count       = grammar.Symbols.Count;
            this.tokenSet   = new BitSetType(count);
            this.firsts     = new MutableIntSet[count];
            this.isNullable = new bool[count];

            MaxRuleSize = grammar.Productions.Select(r => r.PatternTokens.Length).Max();
            Build();
        }
예제 #2
0
        public Lalr1Dfa(GrammarAnalysis grammar, LrTableOptimizations optimizations)
        {
            this.grammar       = grammar;
            this.Optimizations = optimizations;
            this.TokenSet      = grammar.TokenSet;

            BuildLalr1States();

            if ((Optimizations & LrTableOptimizations.EliminateLr0ReduceStates) != 0)
            {
                EliminateLr0ReduceStates();
            }
        }
예제 #3
0
        private DotState[] BuildLr0ItemSets()
        {
            var result = new List<DotState>();

            var initialItemSet = ClosureLr0(new MutableDotItemSet
                {
                    new DotItem(grammar.AugmentedProduction, 0)
                    {
                        LA = TokenSet.Mutable()
                    }
                });
            result.Add(new DotState(0, initialItemSet));

            bool addedStatesInRound;

            do
            {
                addedStatesInRound = false;

                for (int i = 0; i != result.Count; ++i)
                {
                    var itemSet = result[i].Items;

                    foreach (var token in GetOutTokens(itemSet))
                    {
                        var nextStateItems = GoTo(itemSet, token);

                        CollectClosureLookaheads(nextStateItems, grammar);
                        if (nextStateItems.Count == 0)
                        {
                            throw new InvalidOperationException("Internal error: next state cannot be empty");
                        }

                        var nextState = result.Find(state => state.Items.Equals(nextStateItems));
                        if (nextState == null)
                        {
                            addedStatesInRound = true;
                            nextState = new DotState(result.Count, nextStateItems);
                            result.Add(nextState);
                        }

                        if (result[i].AddTransition(token, nextState, TokenSet))
                        {
                            addedStatesInRound = true;
                        }
                    }
                }
            }
            while (addedStatesInRound);

            StateSet = new BitSetType(result.Count);

            return result.ToArray();
        }
예제 #4
0
        public void addall_with_set_of_different_size(IntSet set)
        {
            var otherSetType = new BitSetType(10);
            var other = otherSetType.Of(2, 5, 9);

            MutableIntSet editedSet = set.EditCopy();
            editedSet.AddAll(other);
            Assert.IsTrue(editedSet.IsSupersetOf(other));
            Assert.IsTrue(set.Union(other).SetEquals(editedSet));
            IntSet result = editedSet.CompleteAndDestroy();
            Assert.IsTrue(result.IsSupersetOf(other));
            Assert.IsTrue(set.Union(other).SetEquals(result));
        }
예제 #5
0
        public void intersect_with_set_of_different_size(IntSet x)
        {
            var otherSetType = new BitSetType(10);
            var y = otherSetType.Of(2, 5, 9);

            var intersection = x.Intersect(y);
            var hsIntersection = new HashSet<int>(x);
            hsIntersection.IntersectWith(new HashSet<int>(y));
            CollectionAssert.AreEquivalent(hsIntersection, hsIntersection);

            set_is_optimized(intersection);
        }
예제 #6
0
        public void equility_and_hash_to_set_with_different_size_works_according_to_the_content(IntSet x, IntSet yOfSameType)
        {
            BitSetType otherSetType = new BitSetType(10);
            var y = yOfSameType.Intersect(otherSetType.All);
            bool equals = x.Equals(y);
            bool setEquals = x.SetEquals(y);
            bool hsEquals = new HashSet<int>(x).SetEquals(new HashSet<int>(y));

            Assert.AreEqual(hsEquals, equals);
            Assert.AreEqual(hsEquals, setEquals);
            if (equals)
            {
                Assert.AreEqual(x.GetHashCode(), y.GetHashCode());
            }
            else
            {
                // Uncomment for hashing failure statistics
                // Assert.AreNotEqual(x.GetHashCode(), y.GetHashCode());
            }
        }
예제 #7
0
        public void complement_with_set_of_different_size_returns_correct_result(IntSet set)
        {
            var otherSetType = new BitSetType(10);
            var y = otherSetType.Of(2, 5, 9);

            var got = set.Complement(y);
            foreach (var item in set)
            {
                Assert.IsTrue(!got.Contains(item));
            }

            foreach (var item in y)
            {
                Assert.IsTrue(got.Contains(item) || set.Contains(item));
            }

            int countToCheck = 1000;
            foreach (var item in got)
            {
                Assert.IsFalse(set.Contains(item));
                if (--countToCheck == 0)
                {
                    break;
                }
            }

            set_is_optimized(got);
        }