init
This commit is contained in:
commit
671f259cb6
102
main.go
Normal file
102
main.go
Normal 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)
|
||||
}
|
Loading…
Reference in a new issue