private static String ToDotString(PredictionContext context) { StringBuilder nodes = new StringBuilder(); StringBuilder edges = new StringBuilder(); IDictionary <PredictionContext, PredictionContext> visited = new IdentityHashMap <PredictionContext, PredictionContext>(); IDictionary <PredictionContext, int> contextIds = new IdentityHashMap <PredictionContext, int>(); Stack <PredictionContext> workList = new Stack <PredictionContext>(); visited[context] = context; contextIds[context] = contextIds.Count; workList.Push(context); while (workList.Count > 0) { PredictionContext current = workList.Pop(); nodes.Append(" s").Append(contextIds[current]).Append('['); if (current.Size > 1) { nodes.Append("shape=record, "); } nodes.Append("label=\""); if (current.IsEmpty) { nodes.Append(PredictionContext.IsEmptyLocal(current) ? '*' : '$'); } else if (current.Size > 1) { for (int i = 0; i < current.Size; i++) { if (i > 0) { nodes.Append('|'); } nodes.Append("<p").Append(i).Append('>'); if (current.GetReturnState(i) == PredictionContext.EmptyFullStateKey) { nodes.Append('$'); } else if (current.GetReturnState(i) == PredictionContext.EmptyLocalStateKey) { nodes.Append('*'); } } } else { nodes.Append(contextIds[current]); } nodes.AppendLine("\"];"); for (int i = 0; i < current.Size; i++) { if (current.GetReturnState(i) == PredictionContext.EmptyFullStateKey || current.GetReturnState(i) == PredictionContext.EmptyLocalStateKey) { continue; } if (!visited.ContainsKey(current.GetParent(i))) { visited[current.GetParent(i)] = current.GetParent(i); contextIds[current.GetParent(i)] = contextIds.Count; workList.Push(current.GetParent(i)); } edges.Append(" s").Append(contextIds[current]); if (current.Size > 1) { edges.Append(":p").Append(i); } edges.Append("->"); edges.Append('s').Append(contextIds[current.GetParent(i)]); edges.Append("[label=\"").Append(current.GetReturnState(i)).Append("\"]"); edges.AppendLine(";"); } } StringBuilder builder = new StringBuilder(); builder.AppendLine("digraph G {"); builder.AppendLine("rankdir=LR;"); builder.Append(nodes); builder.Append(edges); builder.AppendLine("}"); return(builder.ToString()); }