-
Notifications
You must be signed in to change notification settings - Fork 0
/
stack.go
109 lines (91 loc) · 1.94 KB
/
stack.go
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
package jsoniterator
import (
"encoding/json"
"strings"
)
type Stack []jsonToken
// IsEmpty: check if stack is empty
func (s *Stack) IsEmpty() bool {
return len(*s) == 0
}
// String: returns items separated by dot
func (s *Stack) String() string {
if len(*s) == 0 {
return ""
}
var b strings.Builder
b.WriteString((*s)[0].String())
for _, s := range (*s)[1:] {
b.WriteString(".")
b.WriteString(s.String())
}
return b.String()
}
// Push a new value onto the stack
func (s *Stack) Push(str jsonToken) {
*s = append(*s, str)
}
// Peek a value without pop
func (s *Stack) Peek() jsonToken {
index := len(*s) - 1
return (*s)[index]
}
// Pop Removes and returns top element of the stack. Return false if stack is empty.
func (s *Stack) Pop() (jsonToken, bool) {
if s.IsEmpty() {
return jsonToken{}, false
} else {
index := len(*s) - 1
element := (*s)[index]
*s = (*s)[:index]
return element, true
}
}
type jsonToken struct {
json.Token
}
const (
objStart = json.Delim('{')
objEnd = json.Delim('}')
arrayStart = json.Delim('[')
arrayEnd = json.Delim(']')
)
func (j *jsonToken) String() string {
switch j.Token.(type) {
case string:
return j.Token.(string)
case json.Delim:
return j.Token.(json.Delim).String()
}
return ""
}
func (j *jsonToken) IsDelim() bool {
_, ok := j.Token.(json.Delim)
return ok
}
func (j *jsonToken) checkDelim(delim json.Delim) bool {
if v, ok := j.Token.(json.Delim); ok {
return v == delim
}
return false
}
func (j *jsonToken) IsArrayStart() bool {
return j.checkDelim(arrayStart)
}
func (j *jsonToken) IsArrayEnd() bool {
return j.checkDelim(arrayEnd)
}
func (j *jsonToken) IsObjStart() bool {
return j.checkDelim(objStart)
}
func (j *jsonToken) IsObjEnd() bool {
return j.checkDelim(objEnd)
}
func (j *jsonToken) IsName() bool {
_, ok := j.Token.(string)
return ok
}
func NewJsonToken(token json.Token) jsonToken {
// TODO: Do not allow numbers, null
return jsonToken{token}
}