commit 671f259cb6c35eac5d5113165350adc40b9a0cf0 Author: Timofey Khoruzhii Date: Sun Apr 16 02:01:24 2023 +0300 init diff --git a/main.go b/main.go new file mode 100644 index 0000000..04a39e0 --- /dev/null +++ b/main.go @@ -0,0 +1,102 @@ +package main + +import ( + "bufio" + "fmt" + "os" + "strconv" + "strings" +) + +type Node struct { + Name string + Children []*Node +} + +func ParseTree(s string) *Node { + // Split string into name and children parts + var name string + var childrenStr string + if idx := strings.Index(s, "<"); idx >= 0 { + if idx+1 < len(s)-1 { + name = strings.TrimSpace(s[:idx]) + childrenStr = s[idx+1 : len(s)-1] + } else { + name = strings.TrimSpace(s[:len(s)-2]) + } + } else { + name = strings.TrimSpace(s) + } + + // Create new node + node := &Node{Name: name} + + // Parse children + if childrenStr != "" { + b := 0 + last_child := 0 + for i, symb := range childrenStr { + if symb == '<' { + b += 1 + } else if symb == '>' { + b -= 1 + if b == 0 { + childNode := ParseTree(childrenStr[last_child : i+1]) + node.Children = append(node.Children, childNode) + last_child = i + 2 + } + } else if symb == ',' && b == 0 { + if last_child < i { + childNode := ParseTree(childrenStr[last_child:i]) + node.Children = append(node.Children, childNode) + last_child = i + 1 + } + } + } + if last_child < len(childrenStr) { + childNode := ParseTree(childrenStr[last_child:]) + node.Children = append(node.Children, childNode) + } + } + + return node +} + +func ToGraphviz(node *Node) string { + var sb strings.Builder + sb.WriteString("digraph {\n") + + // Recursive function to add nodes and edges to string builder + var traverse func(n *Node) + traverse = func(n *Node) { + // Add node to Graphviz string + sb.WriteString(fmt.Sprintf(" \"%p\" [label=%s];\n", n, strconv.Quote(n.Name))) + + // Traverse children and add edges + for _, child := range n.Children { + sb.WriteString(fmt.Sprintf(" \"%p\" -> \"%p\";\n", n, child)) + traverse(child) + } + } + + traverse(node) + sb.WriteString("}") + + return sb.String() +} + +func main() { + // Read all data from stdin + scanner := bufio.NewScanner(os.Stdin) + var typeStr string + for scanner.Scan() { + typeStr += scanner.Text() + "\n" + } + + // Apply the formatter function to the input string + root := ParseTree(typeStr) + graph := ToGraphviz(root) + + // Print the result + fmt.Println(graph) +}