Exemple #1
0
        static Lrfa _ToLrfa(CfgDocument cfg, IProgress <CfgLalr1Progress> progress)
        {
            if (null != progress)
            {
                progress.Report(new CfgLalr1Progress(CfgLalr1Status.ComputingStates, 0));
            }
            // TODO: this takes a long time sometimes
            var map = new Dictionary <ICollection <LRItem>, Lrfa>(_LRItemSetComparer.Default);
            // create an augmented grammar - add rule {start} -> [[StartId]]
            var start = new CfgRule(cfg.GetAugmentedStartId(cfg.StartSymbol), new string[] { cfg.StartSymbol });
            var cl    = new HashSet <LRItem>();

            cl.Add(new LRItem(start, 0));
            _FillLRClosureInPlace(cfg, progress, cl);
            var lrfa  = new Lrfa(true, cl);
            var items = cl.Count;

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

            while (!done)
            {
                done = true;
                var arr = map.Keys.ToArray();
                for (var i = 0; i < arr.Length; ++i)
                {
                    var itemSet = arr[i];
                    foreach (var item in itemSet)
                    {
                        var next = item.RightIndex < item.Rule.Right.Count ? item.Rule.Right[item.RightIndex] : null;
                        if (item.RightIndex < item.Rule.Right.Count)
                        {
                            var n = _FillLRMove(cfg, itemSet, next, progress);
                            if (!_ContainsItemSet(map.Keys, n))
                            {
                                done = false;
                                var npda = new Lrfa(true, n);
                                map.Add(n, npda);
                                items += n.Count;
                                if (null != progress)
                                {
                                    progress.Report(new CfgLalr1Progress(CfgLalr1Status.ComputingConfigurations, items));
                                }
                            }
                            map[itemSet].Transitions[next] = map[n];
                        }
                    }
                }
                if (!done)
                {
                    oc = map.Count;
                    if (null != progress)
                    {
                        progress.Report(new CfgLalr1Progress(CfgLalr1Status.ComputingStates, oc));
                    }
                }
            }
            return(lrfa);
        }
Exemple #2
0
        static CfgDocument _ToLRTransitionGrammar(CfgDocument cfg, Lrfa lrfa, IProgress <CfgLalr1Progress> progress)
        {
            var result   = new CfgDocument();
            var closure  = new List <Lrfa>();
            var itemSets = new List <ICollection <LRItem> >();

            lrfa.FillClosure(closure);
            foreach (var p in closure)
            {
                itemSets.Add(p.AcceptSymbol);
            }

            _LrtSymbol start = null;
            int        j     = 0;

            foreach (var p in closure)
            {
                if (null != progress)
                {
                    progress.Report(new CfgLalr1Progress(CfgLalr1Status.CreatingLookaheadGrammar, j));
                }

                int si = itemSets.IndexOf(p.AcceptSymbol, _LRItemSetComparer.Default);

                foreach (var item in p.AcceptSymbol)
                {
                    if (0 == item.RightIndex)
                    {
                        var next = item.RightIndex < item.Rule.Right.Count ? item.Rule.Right[item.RightIndex] : null;
                        var rule = item.Rule;
                        if (item.RightIndex < item.Rule.Right.Count)
                        {
                            int  dst = -1;
                            Lrfa dsts;
                            if (p.Transitions.ContainsKey(rule.Left))
                            {
                                dsts = p.Transitions[rule.Left];
                                dst  = itemSets.IndexOf(dsts.AcceptSymbol, _LRItemSetComparer.Default);
                            }

                            _LrtSymbol left = new _LrtSymbol(si, rule.Left, dst);
                            if (null == start)
                            {
                                start = left;
                            }
                            var right = new List <string>();
                            var pc    = p;
                            foreach (var sym in rule.Right)
                            {
                                int        s1 = itemSets.IndexOf(pc.AcceptSymbol, _LRItemSetComparer.Default);
                                var        pt = pc.Transitions[sym];
                                int        s2 = itemSets.IndexOf(pt.AcceptSymbol, _LRItemSetComparer.Default);
                                _LrtSymbol n  = new _LrtSymbol(s1, sym, s2);
                                right.Add(n.ToString());
                                pc = pt;
                            }
                            result.Rules.Add(new CfgRule(left.ToString(), right));
                        }
                    }
                }
                ++j;
            }
            result.StartSymbol = start.ToString();
            return(result);
        }