/// <summary>Generates a Unique ID for a parse tree node</summary> /// <param name="tree">parse tree to generate the id for</param> /// <returns>ID for the node</returns> /// <remarks> /// This is useful when generating various graph visualization file formats as /// they normally need unique IDs for each node to maintain proper references /// between the nodes. /// </remarks> public static string GetUniqueNodeId(this IParseTree tree) { var bldr = new StringBuilder(tree.GetHashCode( ).ToString(CultureInfo.InvariantCulture)); if (tree.Parent != null) { bldr.Append(tree.Parent.GetChildIndex(tree)); bldr.Append(tree.Parent.GetUniqueNodeId( )); } return(bldr.ToString( )); }
static void OutDot(StringBuilder sb, IParseTree tree) { var hc = tree.GetHashCode(); if (low_ints.TryGetValue(hc, out int low_hc)) { hc = low_hc; } else { low_ints[hc] = gen++; hc = gen - 1; } if (tree is ParserRuleContext) { var name = "\"" + hc + " " + tree.GetType().Name.Replace("Context", "") + "\""; for (int i = 0; i < tree.ChildCount; ++i) { var c = tree.GetChild(i); var chc = c.GetHashCode(); if (low_ints.TryGetValue(chc, out int low_chc)) { chc = low_chc; } else { low_ints[chc] = gen++; chc = gen - 1; } string cname; if (c is TerminalNodeImpl) { cname = ("\"" + chc + " " + c.GetText() + "\""); } else { cname = ("\"" + chc + " " + c.GetType().Name.Replace("Context", "") + "\""); } sb.AppendLine(name + " -> " + cname); OutDot(sb, c); } } else if (tree is TerminalNodeImpl) { } else { } }
/// <summary> /// Serializing parse tree to DOT using recursive tree lookup. /// </summary> /// <param name="node"> Current parse tree node in lookup. </param> private static void ToDotRecursive(IParseTree node, StringBuilder buf) { string nodeName = Regex.Replace(node.GetType().Name, "Context$", string.Empty); string nodeHash = node.GetHashCode().ToString(); for (int i = 0; i < node.ChildCount; i++) { string childName = Regex.Replace(node.GetChild(i).GetType().Name, "Context$", string.Empty); string childHash = node.GetChild(i).GetHashCode().ToString(); string childText = node.GetChild(i).GetText(); buf.AppendLine( $"\"{nodeHash}\n{nodeName}\" -> \"{childHash}\n{childName}" + $"{((node.GetChild(i).ChildCount == 0) ? "\nToken = \\\"" + Escape(childText) + "\\\"" : string.Empty)}\"\n"); ToDotRecursive(node.GetChild(i), buf); } }