Example #1
0
        _LR0ItemSet _FillLRMove(_LR0ItemSet itemSet, string input, IProgress <CfgLRProgress> progress, _LR0ItemSet result = null)
        {
            if (null == result)
            {
                result = new _LR0ItemSet();
            }
            int i = 0;

            foreach (var item in itemSet.Items)
            {
                if (null != progress)
                {
                    progress.Report(new CfgLRProgress(CfgLRStatus.ComputingMove, i));
                }
                var next = item.Next;
                if (!item.IsEnd)
                {
                    if (Equals(next, input))
                    {
                        var lri = new _LR0Item(item.Left, item.Right, item.RightIndex + 1);
                        result.AddItem(lri);
                    }
                }
                ++i;
            }
            _FillLRClosureInPlace(progress, result);
            return(result);
        }
Example #2
0
        static int _IndexOfItemSet(IEnumerable <_LR0ItemSet> sets, _LR0ItemSet set)
        {
            var i = 0;

            foreach (var lris in sets)
            {
                if (lris.Equals(set))
                {
                    return(i);
                }
                ++i;
            }
            return(-1);
        }
Example #3
0
        void _FillLRClosureInPlace(IProgress <CfgLRProgress> progress, _LR0ItemSet result)
        {
            var done = false;

            while (!done)
            {
                done = true;
                var l = new _LR0Item[result.Items.Count];
                result.Items.CopyTo(l, 0);
                for (var i = 0; i < l.Length; i++)
                {
                    if (null != progress)
                    {
                        progress.Report(new CfgLRProgress(CfgLRStatus.ComputingClosure, i));
                    }
                    var item = l[i];
                    var next = item.Next;
                    if (!item.IsEnd || item.IsNil)
                    {
                        if (IsNonTerminal(next))
                        {
                            for (int jc = Rules.Count, j = 0; j < jc; ++j)
                            {
                                var r = Rules[j];
                                if (r.Left == next)
                                {
                                    var lri = new _LR0Item(r, 0);
                                    if (result.AddItem(lri))
                                    {
                                        done = false;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
Example #4
0
        _LRFA _ToLRFA(IProgress <CfgLRProgress> progress)
        {
            if (null != progress)
            {
                progress.Report(new CfgLRProgress(CfgLRStatus.ComputingStates, 0));
            }
            var moves = new Dictionary <KeyValuePair <_LR0ItemSet, string>, _LR0ItemSet>();
            // TODO: this takes a long time sometimes
            var map = new Dictionary <_LR0ItemSet, _LRFA>();
            // create an augmented grammar - add rule {start} -> [[StartId]]
            var ss    = StartSymbol;
            var start = new CfgRule(GetAugmentedStartId(ss), new string[] { ss });
            var cl    = new _LR0ItemSet();

            cl.AddItem(new _LR0Item(start, 0));

            _FillLRClosureInPlace(progress, cl);
            var lrfa = new _LRFA();

            lrfa.Accept = cl;
            var items = cl.Items.Count;

            map.Add(cl, lrfa);
            var done = false;
            int oc;

            while (!done)
            {
                done = true;
                var arr = new _LR0ItemSet[map.Keys.Count];
                map.Keys.CopyTo(arr, 0);
                for (var i = 0; i < arr.Length; ++i)
                {
                    var itemSet = arr[i];
                    foreach (var item in itemSet.Items)
                    {
                        var next = item.Next;
                        if (!item.IsEnd)
                        {
                            _LR0ItemSet n;
                            var         key = new KeyValuePair <_LR0ItemSet, string>(itemSet, next);
                            if (!moves.TryGetValue(key, out n))
                            {
                                n = _FillLRMove(itemSet, next, progress);
                                moves.Add(key, n);
                            }
                            if (!map.ContainsKey(n))
                            {
                                done = false;

                                var npda = new _LRFA();
                                npda.Accept = n;
                                map.Add(n, npda);
                                items += n.Items.Count;
                                if (null != progress)
                                {
                                    progress.Report(new CfgLRProgress(CfgLRStatus.ComputingConfigurations, items));
                                }
                            }

                            map[itemSet].Transitions[next] = map[n];
                        }
                    }
                }
                if (!done)
                {
                    oc = map.Count;
                    if (null != progress)
                    {
                        progress.Report(new CfgLRProgress(CfgLRStatus.ComputingStates, oc));
                    }
                }
            }
            return(lrfa);
        }