public void GenerateContinuations() { foreach (var continuation in Key.Where(x => !x.IsFinished).GroupBy(x => x.NextPattern)) { var key = new StateKey(continuation.Select(x => x.NextProduction), AllProductions); Continuations.Add(continuation.Key, Machine.GetOrCreateNode(key)); } var finished = Key.Where(x => x.IsFinished).ToArray(); if (finished.Length == 1) { CompletedProduction = finished[0]; } else if (finished.Length > 1) { var maxValue = finished.Max(x => x.Precedence.Value); var maxFinished = finished.Where(x => x.Precedence.Value == maxValue).ToArray(); if (maxFinished.Length == 1) { CompletedProduction = finished.OrderBy(x => x.Precedence.Value).First(); } else { // TODO: better error message throw new InvalidOperationException("Grammar is ambiguous"); } } }
public StateNode(StateKey Key, StateMachine machine, Dictionary <string, Production[]> allProductions) { this.Key = Key; Continuations = new Dictionary <StackItemPattern, StateNode>(); Machine = machine; AllProductions = allProductions; }
public StateNode GetOrCreateNode(StateKey key) { if (!nodes.ContainsKey(key)) { nodes[key] = new StateNode(key, this, AllProductions); // DONT do this in the constructor: We need this item to exist in the dict before this is called. nodes[key].GenerateContinuations(); } return(nodes[key]); }