132 lines
2.2 KiB
Go
132 lines
2.2 KiB
Go
|
package jsonpath
|
||
|
|
||
|
import (
|
||
|
"errors"
|
||
|
"fmt"
|
||
|
)
|
||
|
|
||
|
type sliceLexer struct {
|
||
|
lex
|
||
|
input []byte // the []byte being scanned.
|
||
|
start Pos // start position of this Item.
|
||
|
pos Pos // current position in the input
|
||
|
}
|
||
|
|
||
|
func NewSliceLexer(input []byte, initial stateFn) *sliceLexer {
|
||
|
l := &sliceLexer{
|
||
|
lex: newLex(initial),
|
||
|
input: input,
|
||
|
}
|
||
|
return l
|
||
|
}
|
||
|
|
||
|
func (l *sliceLexer) take() int {
|
||
|
if int(l.pos) >= len(l.input) {
|
||
|
return eof
|
||
|
}
|
||
|
r := int(l.input[l.pos])
|
||
|
l.pos += 1
|
||
|
return r
|
||
|
}
|
||
|
|
||
|
func (l *sliceLexer) takeString() error {
|
||
|
curPos := l.pos
|
||
|
inputLen := len(l.input)
|
||
|
|
||
|
if int(curPos) >= inputLen {
|
||
|
return errors.New("End of file where string expected")
|
||
|
}
|
||
|
|
||
|
cur := int(l.input[curPos])
|
||
|
curPos++
|
||
|
if cur != '"' {
|
||
|
l.pos = curPos
|
||
|
return fmt.Errorf("Expected \" as start of string instead of %#U", cur)
|
||
|
}
|
||
|
|
||
|
var previous int
|
||
|
looper:
|
||
|
for {
|
||
|
if int(curPos) >= inputLen {
|
||
|
l.pos = curPos
|
||
|
return errors.New("End of file where string expected")
|
||
|
}
|
||
|
cur := int(l.input[curPos])
|
||
|
curPos++
|
||
|
if cur == '"' {
|
||
|
if previous == noValue || previous != '\\' {
|
||
|
break looper
|
||
|
} else {
|
||
|
l.take()
|
||
|
}
|
||
|
}
|
||
|
|
||
|
previous = cur
|
||
|
}
|
||
|
l.pos = curPos
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func (l *sliceLexer) peek() int {
|
||
|
if int(l.pos) >= len(l.input) {
|
||
|
return eof
|
||
|
}
|
||
|
return int(l.input[l.pos])
|
||
|
}
|
||
|
|
||
|
func (l *sliceLexer) emit(t int) {
|
||
|
l.setItem(t, l.start, l.input[l.start:l.pos])
|
||
|
l.hasItem = true
|
||
|
|
||
|
// Ignore whitespace after this token
|
||
|
for int(l.pos) < len(l.input) {
|
||
|
r := l.input[l.pos]
|
||
|
if r == ' ' || r == '\t' || r == '\r' || r == '\n' {
|
||
|
l.pos++
|
||
|
} else {
|
||
|
break
|
||
|
}
|
||
|
}
|
||
|
|
||
|
l.start = l.pos
|
||
|
}
|
||
|
|
||
|
func (l *sliceLexer) setItem(typ int, pos Pos, val []byte) {
|
||
|
l.item.typ = typ
|
||
|
l.item.pos = pos
|
||
|
l.item.val = val
|
||
|
}
|
||
|
|
||
|
func (l *sliceLexer) ignore() {
|
||
|
l.start = l.pos
|
||
|
}
|
||
|
|
||
|
func (l *sliceLexer) next() (*Item, bool) {
|
||
|
for {
|
||
|
if l.currentStateFn == nil {
|
||
|
break
|
||
|
}
|
||
|
|
||
|
l.currentStateFn = l.currentStateFn(l, &l.stack)
|
||
|
|
||
|
if l.hasItem {
|
||
|
l.hasItem = false
|
||
|
return &l.item, true
|
||
|
}
|
||
|
}
|
||
|
return &l.item, false
|
||
|
}
|
||
|
|
||
|
func (l *sliceLexer) errorf(format string, args ...interface{}) stateFn {
|
||
|
l.setItem(lexError, l.start, []byte(fmt.Sprintf(format, args...)))
|
||
|
l.start = l.pos
|
||
|
l.hasItem = true
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func (l *sliceLexer) reset() {
|
||
|
l.start = 0
|
||
|
l.pos = 0
|
||
|
l.lex = newLex(l.initialState)
|
||
|
}
|