Added minor improvements

This commit is contained in:
Aleksandr Petrukhin
2017-01-24 17:45:55 +03:00
parent 30ec53d60e
commit dec2e63b78
+63 -36
View File
@@ -6,15 +6,15 @@ package jlexer
import (
"encoding/base64"
"errors"
"fmt"
"io"
"reflect"
"strconv"
"unicode"
"unicode/utf16"
"unicode/utf8"
"unsafe"
"errors"
"unicode/utf16"
"unicode"
)
// tokenKind determines type of a token.
@@ -51,12 +51,11 @@ type Lexer struct {
UseMultipleErrors bool // If we want to use multiple errors.
fatalError error // Fatal error occured during lexing. It is usually a syntax error.
nowSem bool // If semantic error occured during parsing.
multipleErrors []*LexerError // Semantic errors occured during lexing. Marshalling will be continued after finding this errors.
}
// fetchToken scans the input for the next token.
func (r *Lexer) fetchToken() {
// FetchToken scans the input for the next token.
func (r *Lexer) FetchToken() {
r.token.kind = tokenUndef
r.start = r.pos
@@ -395,7 +394,7 @@ func (r *Lexer) scanToken() {
return
}
r.fetchToken()
r.FetchToken()
}
// consume resets the current token to allow scanning the next one.
@@ -450,7 +449,7 @@ func (r *Lexer) errInvalidToken(expected string) {
r.addNonfatalError(&LexerError{
Reason: fmt.Sprintf("expected %s", expected),
Offset: r.start,
Data: string(r.Data[r.start:]),
Data: string(r.Data[r.start:r.pos]),
})
return
}
@@ -468,10 +467,14 @@ func (r *Lexer) errInvalidToken(expected string) {
}
}
func (r *Lexer) GetPos() int {
return r.pos
}
// Delim consumes a token and verifies that it is the given delimiter.
func (r *Lexer) Delim(c byte) {
if r.token.kind == tokenUndef && r.Ok() {
r.fetchToken()
r.FetchToken()
}
if !r.Ok() || r.token.delimValue != c {
@@ -485,7 +488,7 @@ func (r *Lexer) Delim(c byte) {
// IsDelim returns true if there was no scanning error and next token is the given delimiter.
func (r *Lexer) IsDelim(c byte) bool {
if r.token.kind == tokenUndef && r.Ok() {
r.fetchToken()
r.FetchToken()
}
return !r.Ok() || r.token.delimValue == c
}
@@ -493,7 +496,7 @@ func (r *Lexer) IsDelim(c byte) bool {
// Null verifies that the next token is null and consumes it.
func (r *Lexer) Null() {
if r.token.kind == tokenUndef && r.Ok() {
r.fetchToken()
r.FetchToken()
}
if !r.Ok() || r.token.kind != tokenNull {
r.errInvalidToken("null")
@@ -504,7 +507,7 @@ func (r *Lexer) Null() {
// IsNull returns true if the next token is a null keyword.
func (r *Lexer) IsNull() bool {
if r.token.kind == tokenUndef && r.Ok() {
r.fetchToken()
r.FetchToken()
}
return r.Ok() && r.token.kind == tokenNull
}
@@ -512,7 +515,7 @@ func (r *Lexer) IsNull() bool {
// Skip skips a single token.
func (r *Lexer) Skip() {
if r.token.kind == tokenUndef && r.Ok() {
r.fetchToken()
r.FetchToken()
}
r.consume()
}
@@ -605,28 +608,33 @@ func (r *Lexer) Consumed() {
}
}
func (r *Lexer) unsafeString() (string, []byte) {
if r.token.kind == tokenUndef && r.Ok() {
r.FetchToken()
}
if !r.Ok() || r.token.kind != tokenString {
r.errInvalidToken("string")
return "", nil
}
bytes := r.token.byteValue
ret := bytesToStr(r.token.byteValue)
r.consume()
return ret, bytes
}
// UnsafeString returns the string value if the token is a string literal.
//
// Warning: returned string may point to the input buffer, so the string should not outlive
// the input buffer. Intended pattern of usage is as an argument to a switch statement.
func (r *Lexer) UnsafeString() string {
if r.token.kind == tokenUndef && r.Ok() {
r.fetchToken()
}
if !r.Ok() || r.token.kind != tokenString {
r.errInvalidToken("string")
return ""
}
ret := bytesToStr(r.token.byteValue)
r.consume()
ret, _ := r.unsafeString()
return ret
}
// String reads a string literal.
func (r *Lexer) String() string {
if r.token.kind == tokenUndef && r.Ok() {
r.fetchToken()
r.FetchToken()
}
if !r.Ok() || r.token.kind != tokenString {
r.errInvalidToken("string")
@@ -640,7 +648,7 @@ func (r *Lexer) String() string {
// Bytes reads a string literal and base64 decodes it into a byte slice.
func (r *Lexer) Bytes() []byte {
if r.token.kind == tokenUndef && r.Ok() {
r.fetchToken()
r.FetchToken()
}
if !r.Ok() || r.token.kind != tokenString {
r.errInvalidToken("string")
@@ -662,7 +670,7 @@ func (r *Lexer) Bytes() []byte {
// Bool reads a true or false boolean keyword.
func (r *Lexer) Bool() bool {
if r.token.kind == tokenUndef && r.Ok() {
r.fetchToken()
r.FetchToken()
}
if !r.Ok() || r.token.kind != tokenBool {
r.errInvalidToken("bool")
@@ -675,7 +683,7 @@ func (r *Lexer) Bool() bool {
func (r *Lexer) number() string {
if r.token.kind == tokenUndef && r.Ok() {
r.fetchToken()
r.FetchToken()
}
if !r.Ok() || r.token.kind != tokenNumber {
r.errInvalidToken("number")
@@ -697,6 +705,7 @@ func (r *Lexer) Uint8() uint8 {
r.addNonfatalError(&LexerError{
Offset: r.start,
Reason: err.Error(),
Data: s,
})
}
return uint8(n)
@@ -713,6 +722,7 @@ func (r *Lexer) Uint16() uint16 {
r.addNonfatalError(&LexerError{
Offset: r.start,
Reason: err.Error(),
Data: s,
})
}
return uint16(n)
@@ -729,6 +739,7 @@ func (r *Lexer) Uint32() uint32 {
r.addNonfatalError(&LexerError{
Offset: r.start,
Reason: err.Error(),
Data: s,
})
}
return uint32(n)
@@ -745,6 +756,7 @@ func (r *Lexer) Uint64() uint64 {
r.addNonfatalError(&LexerError{
Offset: r.start,
Reason: err.Error(),
Data: s,
})
}
return n
@@ -765,6 +777,7 @@ func (r *Lexer) Int8() int8 {
r.addNonfatalError(&LexerError{
Offset: r.start,
Reason: err.Error(),
Data: s,
})
}
return int8(n)
@@ -781,6 +794,7 @@ func (r *Lexer) Int16() int16 {
r.addNonfatalError(&LexerError{
Offset: r.start,
Reason: err.Error(),
Data: s,
})
}
return int16(n)
@@ -797,6 +811,7 @@ func (r *Lexer) Int32() int32 {
r.addNonfatalError(&LexerError{
Offset: r.start,
Reason: err.Error(),
Data: s,
})
}
return int32(n)
@@ -813,6 +828,7 @@ func (r *Lexer) Int64() int64 {
r.addNonfatalError(&LexerError{
Offset: r.start,
Reason: err.Error(),
Data: s,
})
}
return n
@@ -823,7 +839,7 @@ func (r *Lexer) Int() int {
}
func (r *Lexer) Uint8Str() uint8 {
s := r.UnsafeString()
s, b := r.unsafeString()
if !r.Ok() {
return 0
}
@@ -833,13 +849,14 @@ func (r *Lexer) Uint8Str() uint8 {
r.addNonfatalError(&LexerError{
Offset: r.start,
Reason: err.Error(),
Data: string(b),
})
}
return uint8(n)
}
func (r *Lexer) Uint16Str() uint16 {
s := r.UnsafeString()
s, b := r.unsafeString()
if !r.Ok() {
return 0
}
@@ -849,13 +866,14 @@ func (r *Lexer) Uint16Str() uint16 {
r.addNonfatalError(&LexerError{
Offset: r.start,
Reason: err.Error(),
Data: string(b),
})
}
return uint16(n)
}
func (r *Lexer) Uint32Str() uint32 {
s := r.UnsafeString()
s, b := r.unsafeString()
if !r.Ok() {
return 0
}
@@ -865,13 +883,14 @@ func (r *Lexer) Uint32Str() uint32 {
r.addNonfatalError(&LexerError{
Offset: r.start,
Reason: err.Error(),
Data: string(b),
})
}
return uint32(n)
}
func (r *Lexer) Uint64Str() uint64 {
s := r.UnsafeString()
s, b := r.unsafeString()
if !r.Ok() {
return 0
}
@@ -881,6 +900,7 @@ func (r *Lexer) Uint64Str() uint64 {
r.addNonfatalError(&LexerError{
Offset: r.start,
Reason: err.Error(),
Data: string(b),
})
}
return n
@@ -891,7 +911,7 @@ func (r *Lexer) UintStr() uint {
}
func (r *Lexer) Int8Str() int8 {
s := r.UnsafeString()
s, b := r.unsafeString()
if !r.Ok() {
return 0
}
@@ -901,13 +921,14 @@ func (r *Lexer) Int8Str() int8 {
r.addNonfatalError(&LexerError{
Offset: r.start,
Reason: err.Error(),
Data: string(b),
})
}
return int8(n)
}
func (r *Lexer) Int16Str() int16 {
s := r.UnsafeString()
s, b := r.unsafeString()
if !r.Ok() {
return 0
}
@@ -917,13 +938,14 @@ func (r *Lexer) Int16Str() int16 {
r.addNonfatalError(&LexerError{
Offset: r.start,
Reason: err.Error(),
Data: string(b),
})
}
return int16(n)
}
func (r *Lexer) Int32Str() int32 {
s := r.UnsafeString()
s, b := r.unsafeString()
if !r.Ok() {
return 0
}
@@ -933,13 +955,14 @@ func (r *Lexer) Int32Str() int32 {
r.addNonfatalError(&LexerError{
Offset: r.start,
Reason: err.Error(),
Data: string(b),
})
}
return int32(n)
}
func (r *Lexer) Int64Str() int64 {
s := r.UnsafeString()
s, b := r.unsafeString()
if !r.Ok() {
return 0
}
@@ -949,6 +972,7 @@ func (r *Lexer) Int64Str() int64 {
r.addNonfatalError(&LexerError{
Offset: r.start,
Reason: err.Error(),
Data: string(b),
})
}
return n
@@ -969,6 +993,7 @@ func (r *Lexer) Float32() float32 {
r.addNonfatalError(&LexerError{
Offset: r.start,
Reason: err.Error(),
Data: s,
})
}
return float32(n)
@@ -985,6 +1010,7 @@ func (r *Lexer) Float64() float64 {
r.addNonfatalError(&LexerError{
Offset: r.start,
Reason: err.Error(),
Data: s,
})
}
return n
@@ -1002,6 +1028,7 @@ func (r *Lexer) AddError(e error) {
func (r *Lexer) addNonfatalError(err *LexerError) {
if r.UseMultipleErrors {
// We don't want to add errors with the same offset.
if len(r.multipleErrors) != 0 && r.multipleErrors[len(r.multipleErrors)-1].Offset == err.Offset {
return
}
@@ -1018,7 +1045,7 @@ func (r *Lexer) GetNonFatalErrors() []*LexerError {
// Interface fetches an interface{} analogous to the 'encoding/json' package.
func (r *Lexer) Interface() interface{} {
if r.token.kind == tokenUndef && r.Ok() {
r.fetchToken()
r.FetchToken()
}
if !r.Ok() {