Example #1
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));
                }
            }
        }