private void ComputeLr0ItemSetKernelsAndGotoLookup(out LrItemSetCollection itemSets, out Dictionary <int, Dictionary <SymbolId, int> > gotos, out int acceptIndex) { itemSets = new LrItemSetCollection(); gotos = new Dictionary <int, Dictionary <SymbolId, int> >(); var itemSetByKernels = new Dictionary <IEnumerable <LrItem>, LrItemSet>(SetEqualityComparer <LrItem> .Default); var queue = new Queue <LrItemSet>(); var startItem = new LrItemSet(new LrItem(this.ProductionRulesBySymbol[this.Init].Single(), 0, true)); this.Lr0ComputeClosureNonterminals(startItem); itemSets.StartState = startItem; acceptIndex = this.ProductionRulesBySymbol[this.Init].Single().Index; startItem.Index = itemSets.Count; itemSets.Add(startItem); itemSetByKernels.Add(startItem.Kernels.ToArray(), startItem); queue.Enqueue(startItem); while (queue.Count > 0) { var itemSet = queue.Dequeue(); var gotoLookup = this.Lr0GotoKernels(itemSet); var gotosForState = new Dictionary <SymbolId, int>(); gotos.Add(itemSet.Index, gotosForState); foreach (var symbol in gotoLookup.Keys) { if (!itemSetByKernels.TryGetValue(gotoLookup[symbol].Kernels, out var gotoState)) { gotoState = gotoLookup[symbol]; this.Lr0ComputeClosureNonterminals(gotoState); gotoState.Index = itemSets.Count; itemSets.Add(gotoState); itemSetByKernels.Add(gotoState.Kernels.ToArray(), gotoState); queue.Enqueue(gotoState); } gotosForState.Add(symbol, gotoState.Index); } } }
private Dictionary <StateKey <SymbolId>, int> ComputeGotoLookup(SymbolMetaDictionary symbolMeta, LrItemSetCollection itemSets) { var gotos = new Dictionary <StateKey <SymbolId>, int>(); var itemSetByKernels = itemSets.ToDictionary(s => s.Kernels.ToArray(), s => s, SetEqualityComparer <LrItem> .Default); foreach (var itemSet in itemSets) { foreach (var sym in symbolMeta.Keys) { // Compute dynamic GOTO var gotoClosure = this.Lr1Closure(symbolMeta, new LrItemSet(itemSet .Where(item => (item.Marker < item.Length) && item.Rule.RuleSymbolIds[item.Marker].Equals(sym)) .Select(item => new LrItem(item.Rule, item.Marker + 1, true)))); if (!gotoClosure.Any()) { continue; } var key = new StateKey <SymbolId>(itemSet.Index, sym); if (gotos.ContainsKey(key)) { continue; } // Match the dynamic GOTO to an actual state if (itemSetByKernels.TryGetValue(gotoClosure.Kernels, out var existingGoto)) { gotos.Add(key, existingGoto.Index); } } } return(gotos); }