private void AnnotateWithProductionsChildren(InteriorNode parent, HashSet <SppfNode> seen, SppfNode left, SppfNode right, int place) { if (!(left is IntermediateNode)) { throw new Exception(); } //if (!(right is SymbolNode)) { // throw new Exception(); //} AnnotateWithProductions(left, seen, parent, place); AnnotateWithProductions(right, seen, parent, place); }
private void AnnotateWithProductionsChildren(InteriorNode parent, HashSet <SppfNode> seen, SppfNode child, int place) { Word parentSymbol = null; if (parent is SymbolNode) { var symbolParent = (SymbolNode)parent; parentSymbol = symbolParent.Symbol; } else { var intermediateParent = (IntermediateNode)parent; if (intermediateParent.Item.CurrentPosition != 1) { throw new Exception("Expected to be at beginning of item"); } parentSymbol = intermediateParent.Item.Production.Rhs[0]; } if (child is SymbolNode) { var symbolChild = (SymbolNode)child; if (parent is SymbolNode) { var symbolParent = (SymbolNode)parent; var production = _grammar.FindProduction((Nonterminal)parentSymbol, new Sentence { symbolChild.Symbol }); symbolParent.AddChild(place, production); } AnnotateWithProductions(symbolChild, seen, parent, place); return; } else if (child is IntermediateNode) { throw new Exception("Don't handle intermediate"); } else if (child is LeafNode) { if (parentSymbol is Nonterminal) { var leafChild = (LeafNode)child; var childSentence = leafChild.GetSentence(); var production = _grammar.FindProduction((Nonterminal)parentSymbol, childSentence); parent.AddChild(place, production); } return; } throw new Exception(); }
// [Sec 4, ES2008] private void BuildTree(Dictionary <SppfNode, SppfNode> nodes, HashSet <Item> processed, InteriorNode node, Item item) { processed.Add(item); if (item.Production.Rhs.Count == 0) { var i = node.EndPosition; var v = NewOrExistingNode(nodes, new SymbolNode(item.Production.Lhs, i, i)); //if there is no SPPF node v labeled (A, i, i) //create one with child node ϵ v.AddFamily(new Family(new EpsilonNode(i, i))); // basically, SymbolNodes with no children have empty children } else if (item.CurrentPosition == 1) { var prevWord = item.PrevWord; if (prevWord.IsTerminal) { var a = (Terminal)prevWord; var i = node.EndPosition; var v = NewOrExistingNode(nodes, new TerminalNode(a, i - 1, i)); node.AddFamily(new Family(v)); } else { var C = (Nonterminal)prevWord; var j = node.StartPosition; var i = node.EndPosition; var v = NewOrExistingNode(nodes, new SymbolNode(C, j, i)); node.AddFamily(new Family(v)); foreach (var reduction in item.Reductions) { if (reduction.Label != j) { continue; } var q = reduction.Item; if (!processed.Contains(q)) { BuildTree(nodes, processed, v, q); } } } } else if (item.PrevWord.IsTerminal) { var a = (Terminal)item.PrevWord; var j = node.StartPosition; var i = node.EndPosition; var v = NewOrExistingNode(nodes, new TerminalNode(a, i - 1, i)); var w = NewOrExistingNode(nodes, new IntermediateNode(item.Decrement(), j, i - 1)); foreach (var predecessor in item.Predecessors) { if (predecessor.Label != i - 1) { continue; } var pPrime = predecessor.Item; if (!processed.Contains(pPrime)) { BuildTree(nodes, processed, w, pPrime); } } node.AddFamily(new Family(w, v)); } else { var C = (Nonterminal)item.PrevWord; foreach (var reduction in item.Reductions) { var l = reduction.Label; var q = reduction.Item; var j = node.StartPosition; var i = node.EndPosition; var v = NewOrExistingNode(nodes, new SymbolNode(C, l, i)); if (!processed.Contains(q)) { BuildTree(nodes, processed, v, q); } var w = NewOrExistingNode(nodes, new IntermediateNode(item.Decrement(), j, l)); foreach (var predecessor in item.Predecessors) { if (predecessor.Label != l) { continue; } var pPrime = predecessor.Item; if (!processed.Contains(pPrime)) { BuildTree(nodes, processed, w, pPrime); } } node.AddFamily(new Family(w, v)); } } }
//TODO this is so horribly terrible. There's got to be a better way of thinking about this structure private void AnnotateWithProductions(SppfNode node, HashSet <SppfNode> seen = null, InteriorNode parent = null, int place = 0) { if (seen == null) { seen = new HashSet <SppfNode>(); } if (node is IntermediateNode) { var intermediateNode = (IntermediateNode)node; var production = intermediateNode.Item.Production; if (intermediateNode.Item.CurrentPosition == production.Rhs.Count - 1) { parent.AddChild(place, production); } } if (seen.Contains(node)) { return; } seen.Add(node); var l = node.Families; for (int i = 0; i < l.Count; i++) { var alternative = l[i]; if (!(node is InteriorNode)) { throw new Exception(); } var members = l[i].Members; if (members.Count == 1) { var child = members[0]; AnnotateWithProductionsChildren((InteriorNode)node, seen, child, i); } else if (members.Count == 2) { var left = members[0]; var right = members[1]; AnnotateWithProductionsChildren((InteriorNode)node, seen, left, right, i); } else { throw new Exception("Should only be 0--2 children"); } } }