_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); }
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); }
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; } } } } } } } }
_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); }