private string GetLabel(SppfNode node)
        {
            if (node.Id > 0)
            {
                return(grammar.Symbols[node.Id].Name + " pos: " + node.Location.Position);
            }

            if (node.NextAlternative != null)
            {
                return(grammar.Symbols[node.GetTokenId(grammar)].Name);
            }

            var production = grammar.Productions[-node.Id];

            if (showRules)
            {
                return(string.Format(
                           "{0} -> {1}",
                           production.Outcome.Name,
                           string.Join(" ", from s in production.Pattern select s.Name)));
            }

            return(production.Outcome.Name);
        }
        void ISppfNodeVisitor.VisitAlternatives(SppfNode alternatives)
        {
            var    token  = alternatives.GetTokenId(grammar);
            var    symbol = grammar.Symbols[token];
            string label  = symbol.Name + " pos: " + alternatives.Location.Position
#if DEBUG
                            + " t: " + currentNode.timestamp
#endif
            ;

            object parentIdentity = currentNodeIdentity;

            graph.AddNode(parentIdentity, label: label, shape: Shape.Rect);

            var familyNode  = alternatives;
            var altIdentity = alternatives.Children ?? new object();

            int altIndex = 0;

            do
            {
                graph.AddEdge(
                    parentIdentity,
                    altIdentity,
                    style: Style.Dotted,
                    label: "alt#" + ++altIndex);

                this.currentNodeIdentity = altIdentity;
                this.currentNode         = familyNode;
                visited.Add(familyNode);
                familyNode.Accept(this, ignoreAlternatives: true);

                familyNode  = familyNode.NextAlternative;
                altIdentity = familyNode;
            }while (familyNode != null);
        }