aboutsummaryrefslogtreecommitdiff
path: root/src/vparse/vparse.go
blob: 624d0a51b77602600a8aced109dae0f56b270602 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
package vparse

import (
	"bufio"
	"io"
	"strings"
)

type Node struct {
	Type       string
	Properties map[string]string
	Children   []Node
}

func parseNode(scanner *bufio.Scanner, nodeType string) Node {
	node := Node{nodeType, make(map[string]string), make([]Node, 0)}

	var lastProperty string
	var expectColon bool = false

SC:
	for scanner.Scan() {

		line := scanner.Text()

		if strings.HasPrefix(line, " ") {
			value := line[1:]
			if expectColon {
				value = strings.SplitN(value, ":", 2)[1]
			}

			node.Properties[lastProperty] += value

			expectColon = false
			continue
		}

		if !strings.Contains(line, ":") {
			lastProperty = line
			expectColon = true
			continue
		}

		splitLine := strings.SplitN(line, ":", 2)

		switch splitLine[0] {

		case "END":
			break SC

		case "BEGIN":
			node.Children = append(node.Children, parseNode(scanner, splitLine[1]))
			break

		default:
			node.Properties[splitLine[0]] = splitLine[1]
			lastProperty = splitLine[0]

		}

	}

	return node
}

func Parse(reader io.Reader) []Node {
	scanner := bufio.NewScanner(reader)
	return parseNode(scanner, "").Children
}