This commit is contained in:
Timofey Khoruzhii 2023-04-16 02:01:24 +03:00
commit 671f259cb6

102
main.go Normal file
View file

@ -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)
}