Example #1
0
        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);
        }
Example #2
0
        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();
        }
Example #3
0
        // [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));
                }
            }
        }
Example #4
0
        //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");
                }
            }
        }