private Dictionary <ParserConstructionItemSet, ItemSetGraphInformation> ConstructStateTransitionGraph() { ParserConstructionItemSet intialStateSet = GetInitialState(); Dictionary <ParserConstructionItemSet, ItemSetGraphInformation> shiftGraph = new Dictionary <ParserConstructionItemSet, ItemSetGraphInformation>(); shiftGraph.Add(intialStateSet, new ItemSetGraphInformation { Id = 0 }); HashSet <ParserConstructionItemSet> processedStates = new HashSet <ParserConstructionItemSet>(); Queue <ParserConstructionItemSet> setsToProcess = new Queue <ParserConstructionItemSet>(); setsToProcess.Enqueue(intialStateSet); while (setsToProcess.Count > 0) { var curSet = setsToProcess.Dequeue(); if (processedStates.Contains(curSet)) { continue; } var curStateInfo = shiftGraph[curSet]; var targetStates = GetShiftedStates(curSet, intialStateSet); foreach (var targetState in targetStates) { if (shiftGraph.TryGetValue(targetState.Value, out var existingTargetStateInfo)) { curStateInfo.ShiftToIds.Add(targetState.Key, existingTargetStateInfo.Id); } else { int newStateId = shiftGraph.Count; shiftGraph.Add(targetState.Value, new ItemSetGraphInformation { Id = newStateId }); curStateInfo.ShiftToIds.Add(targetState.Key, newStateId); setsToProcess.Enqueue(targetState.Value); } } processedStates.Add(curSet); } return(shiftGraph); }
private ParserConstructionItemSet GetShiftedState(IEnumerable <GrammarRuleOffset> offsets, ParserConstructionItemSet initialSet) { var shiftedSeedOffsets = offsets.Select(o => o.Shift()).Where(i => i.IsValid); var result = CalculateItemSetEnclosure(shiftedSeedOffsets); if (_grammar.IsSkipGrammar) { result.UnionWith(initialSet.RuleOffsets); } return(new ParserConstructionItemSet { RuleOffsets = result }); }
private Dictionary <GrammarRuleToken, ParserConstructionItemSet> GetShiftedStates(ParserConstructionItemSet currentSet, ParserConstructionItemSet initialSet) { var result = currentSet .RuleOffsets .Where(o => !o.IsFinal) .GroupBy(o => o.NextToken) .ToDictionary(g => g.Key, g => GetShiftedState(g, initialSet)); if (_grammar.IsSkipGrammar) { result.Add(_grammar.SkipToken, initialSet); } return(result); }