CfgDocument _LRFAToLRExtendedGrammar(_LRFA lrfa, IProgress <CfgLRProgress> progress) { var result = new CfgDocument(); var closure = new List <_LRFA>(); var itemSets = new List <_LR0ItemSet>(); lrfa.FillClosure(closure); foreach (var p in closure) { itemSets.Add(p.Accept); } _LRExtendedSymbol start = null; int j = 0; foreach (var p in closure) { if (null != progress) { progress.Report(new CfgLRProgress(CfgLRStatus.CreatingLRExtendedGrammar, j)); } int si = itemSets.IndexOf(p.Accept); foreach (var item in p.Accept.Items) { if (0 == item.RightIndex) { var next = item.Next; if (!item.IsEnd || item.IsNil) { int dst = -1; _LRFA dsts; if (p.Transitions.ContainsKey(item.Left)) { dsts = p.Transitions[item.Left]; dst = itemSets.IndexOf(dsts.Accept); } _LRExtendedSymbol left = new _LRExtendedSymbol(si, item.Left, dst); if (null == start) { start = left; } var right = new List <string>(); var pc = p; foreach (var sym in item.Right) { int s1 = itemSets.IndexOf(pc.Accept); var pt = pc.Transitions[sym]; int s2 = itemSets.IndexOf(pt.Accept); _LRExtendedSymbol n = new _LRExtendedSymbol(s1, sym, s2); right.Add(n.ToString()); pc = pt; } result.Rules.Add(new CfgRule(left.ToString(), right)); } } } ++j; } result.StartSymbol = start.ToString(); return(result); }
_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); }