Exemple #1
0
        public static CfgLalr1ParseTable ToLalr1ParseTable(this CfgDocument cfg, IProgress <CfgLalr1Progress> progress = null)
        {
            CfgLalr1ParseTable result = null;
            var msgs = TryToLalr1ParseTable(cfg, progress, out result);

            CfgException.ThrowIfErrors(msgs);
            return(result);
        }
Exemple #2
0
 public Lalr1DebugParser(CfgDocument cfg, IEnumerable <Token> tokenizer, CfgLalr1ParseTable parseTable = null)
 {
     _cfg = cfg;
     _PopulateAttrs();
     _stack      = new Stack <int>();
     _tokenEnum  = tokenizer.GetEnumerator();
     _parseTable = parseTable ?? cfg.ToLalr1ParseTable();
     _nodeType   = LRNodeType.Initial;
 }
Exemple #3
0
        public static IList <CfgMessage> TryToLalr1ParseTable(this CfgDocument cfg, IProgress <CfgLalr1Progress> progress, out CfgLalr1ParseTable parseTable)
        {
            var result  = new List <CfgMessage>();
            var start   = cfg.GetAugmentedStartId(cfg.StartSymbol);
            var lrfa    = _ToLrfa(cfg, progress);
            var trnsCfg = _ToLRTransitionGrammar(cfg, lrfa, progress);

            trnsCfg.RebuildCache();
            var closure = new List <Lrfa>();

            parseTable = new CfgLalr1ParseTable();

            var itemSets = new List <ICollection <LRItem> >();

            lrfa.FillClosure(closure);
            var i = 0;

            foreach (var p in closure)
            {
                itemSets.Add(p.AcceptSymbol);
                parseTable.Add(new Dictionary <string, (int RuleOrStateId, string Left, string[] Right)>());
                ++i;
            }
            i = 0;
            foreach (var p in closure)
            {
                foreach (var trn in p.Transitions)
                {
                    var idx = closure.IndexOf(trn.Value);
                    parseTable[i].Add(
                        trn.Key,
                        (idx, null, null)
                        );
                }
                foreach (var item in p.AcceptSymbol)
                {
                    if (Equals(item.Rule.Left, start) && item.RightIndex == item.Rule.Right.Count)
                    {
                        parseTable[i].Add(
                            "#EOS",
                            (-1, null, null));
                        break;
                    }
                }
                ++i;
            }
            var follows = trnsCfg.FillFollows();
            // work on our reductions now
            var map = new Dictionary <CfgRule, ICollection <string> >(_TransitionMergeRuleComparer.Default);

            foreach (var rule in trnsCfg.Rules)
            {
                ICollection <string> f;
                if (!map.TryGetValue(rule, out f))
                {
                    map.Add(rule, follows[rule.Left]);
                }
                else
                {
                    foreach (var o in follows[rule.Left])
                    {
                        if (!f.Contains(o))
                        {
                            f.Add(o);
                        }
                    }
                }
            }
            var j = 0;

            foreach (var mapEntry in map)
            {
                if (null != progress)
                {
                    progress.Report(new CfgLalr1Progress(CfgLalr1Status.ComputingReductions, j));
                }
                var rule  = mapEntry.Key;
                var lr    = _LrtSymbol.Parse(rule.Right[rule.Right.Count - 1]);
                var left  = _LrtSymbol.Parse(rule.Left).Id;
                var right = new List <string>();
                foreach (var s in rule.Right)
                {
                    right.Add(_LrtSymbol.Parse(s).Id);
                }
                var newRule = new CfgRule(left, right);
                if (!Equals(left, start))
                {
                    foreach (var f in mapEntry.Value)
                    {
                        // build the rule data
                        var rr = new string[newRule.Right.Count];
                        for (var ri = 0; ri < rr.Length; ri++)
                        {
                            rr[ri] = newRule.Right[ri];
                        }

                        var iid = _LrtSymbol.Parse(f).Id;
                        (int RuleOrStateId, string Left, string[] Right)tuple;
                        var rid = cfg.Rules.IndexOf(newRule);

                        var newTuple = (RuleOrStateId : rid, Left : newRule.Left, Right : rr);
                        // this gets rid of duplicate entries which crop up in the table
                        if (!parseTable[lr.To].TryGetValue(iid, out tuple))
                        {
                            parseTable[lr.To].Add(_LrtSymbol.Parse(f).Id,
                                                  newTuple);
                        }
                        else
                        {
                            // TODO: Verify this - may need the dragon book
                            if (null == tuple.Right)
                            {
                                var nr  = cfg.Rules[rid];
                                var msg = new CfgMessage(CfgErrorLevel.Warning, -1, string.Format("Shift-Reduce conflict on rule {0}, token {1}", nr, iid), nr.Line, nr.Column, nr.Position);
                                if (!result.Contains(msg))
                                {
                                    result.Add(msg);
                                }
                            }
                            else
                            {
                                if (rid != newTuple.RuleOrStateId)
                                {
                                    var nr  = cfg.Rules[rid];
                                    var msg = new CfgMessage(CfgErrorLevel.Error, -1, string.Format("Reduce-Reduce conflict on rule {0}, token {1}", nr, iid), nr.Line, nr.Column, nr.Position);
                                    if (!result.Contains(msg))
                                    {
                                        result.Add(msg);
                                    }
                                }
                            }
                        }
                    }
                }
                ++j;
            }
            return(result);
        }
Exemple #4
0
 public static IList <CfgMessage> TryToLalr1ParseTable(this CfgDocument cfg, out CfgLalr1ParseTable parseTable)
 => TryToLalr1ParseTable(cfg, null, out parseTable);