public void Step(List <Context> queue) { while (currDefnPos == currDefn.items.Count) { if (parent == null) { queue.Add(this); return; } this.currDefn = parent.currDefn; this.currDefnPos = parent.currDefnPos; if (((Ref)currDefn.items[currDefnPos - 1]).island) { this.activeFeatures = parent.activeFeatures; } this.parent = parent.parent; } DefinitionItem currItem = currDefn.items[currDefnPos]; ++this.currDefnPos; if (currItem is Token) { this.generated = new GenerationCons((Token)currItem, generated); queue.Add(this); } else if (currItem is Ref) { Ref currRef = (Ref)currItem; List <Definition> candidateDefns = grammar.rules[currRef.ruleName]; List <string> newFeats = currRef.island ? new List <string>() : new List <string>(activeFeatures); if (currRef.features != null) { foreach (string feat in currRef.features) { if (grammar.exclusions.ContainsKey(feat)) { foreach (string excluded in grammar.exclusions[feat]) { newFeats.Remove(excluded); } } } newFeats.AddRange(currRef.features); } bool children = false; foreach (Definition candidate in candidateDefns) { if (grammar.CheckFeatures(candidate.checkedFeatures, newFeats)) { if (parent == null || !(candidate == currDefn && currDefn == parent.currDefn)) { children = true; List <string> newFeatsSpec = newFeats; if (candidate.checkedFeatures != null) { bool copied = false; foreach (string checkedFeat in candidate.checkedFeatures) { if (!newFeats.Contains(checkedFeat)) { if (!copied) { copied = true; newFeatsSpec = new List <string>(newFeats); } newFeatsSpec.Add(checkedFeat); } } } queue.Add(new Context(grammar, this, candidate, 0, generated, newFeatsSpec)); } } } if (!children) { Debug.LogWarning("Dead end at ref " + currItem.ToString() + " with active features " + newFeats.ToString() + ", generated so far: " + generated.Flatten()); } } }