-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathlexer.go
86 lines (75 loc) · 1.52 KB
/
lexer.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
package jsonpath
type Pos int
type stateFn func(lexer, *intStack) stateFn
const (
lexError = 0 // must match jsonError and pathError
lexEOF = 1
eof = -1
noValue = -2
)
type Item struct {
typ int
pos Pos // The starting position, in bytes, of this Item in the input string.
val []byte
}
// Used by evaluator
type tokenReader interface {
next() (*Item, bool)
}
// Used by state functions
type lexer interface {
tokenReader
take() int
takeString() error
peek() int
emit(int)
ignore()
errorf(string, ...interface{}) stateFn
reset()
}
type lex struct {
initialState stateFn
currentStateFn stateFn
item Item
hasItem bool
stack intStack
}
func newLex(initial stateFn) lex {
return lex{
initialState: initial,
currentStateFn: initial,
item: Item{},
stack: *newIntStack(),
}
}
func (i *Item) clone() *Item {
ic := Item{
typ: i.typ,
pos: i.pos,
val: make([]byte, len(i.val)),
}
copy(ic.val, i.val)
return &ic
}
func itemsDescription(items []Item, nameMap map[int]string) []string {
vals := make([]string, len(items))
for i, item := range items {
vals[i] = itemDescription(&item, nameMap)
}
return vals
}
func itemDescription(item *Item, nameMap map[int]string) string {
var found bool
val, found := nameMap[item.typ]
if !found {
return string(item.val)
}
return val
}
func typesDescription(types []int, nameMap map[int]string) []string {
vals := make([]string, len(types))
for i, val := range types {
vals[i] = nameMap[val]
}
return vals
}