Skip to content

Commit 141f9c7

Browse files
authored
Merge pull request #393 from iamtakingiteasy/master
Make current token kind public and accessible via Lexer.CurrentToken
2 parents a209843 + 3bd36b7 commit 141f9c7

File tree

2 files changed

+78
-50
lines changed

2 files changed

+78
-50
lines changed

jlexer/lexer.go

Lines changed: 63 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -19,21 +19,21 @@ import (
1919
"github.com/josharian/intern"
2020
)
2121

22-
// tokenKind determines type of a token.
23-
type tokenKind byte
22+
// TokenKind determines type of a token.
23+
type TokenKind byte
2424

2525
const (
26-
tokenUndef tokenKind = iota // No token.
27-
tokenDelim // Delimiter: one of '{', '}', '[' or ']'.
28-
tokenString // A string literal, e.g. "abc\u1234"
29-
tokenNumber // Number literal, e.g. 1.5e5
30-
tokenBool // Boolean literal: true or false.
31-
tokenNull // null keyword.
26+
TokenUndef TokenKind = iota // No token.
27+
TokenDelim // Delimiter: one of '{', '}', '[' or ']'.
28+
TokenString // A string literal, e.g. "abc\u1234"
29+
TokenNumber // Number literal, e.g. 1.5e5
30+
TokenBool // Boolean literal: true or false.
31+
TokenNull // null keyword.
3232
)
3333

3434
// token describes a single token: type, position in the input and value.
3535
type token struct {
36-
kind tokenKind // Type of a token.
36+
kind TokenKind // Type of a token.
3737

3838
boolValue bool // Value if a boolean literal token.
3939
byteValueCloned bool // true if byteValue was allocated and does not refer to original json body
@@ -47,7 +47,7 @@ type Lexer struct {
4747

4848
start int // Start of the current token.
4949
pos int // Current unscanned position in the input stream.
50-
token token // Last scanned token, if token.kind != tokenUndef.
50+
token token // Last scanned token, if token.kind != TokenUndef.
5151

5252
firstElement bool // Whether current element is the first in array or an object.
5353
wantSep byte // A comma or a colon character, which need to occur before a token.
@@ -59,7 +59,7 @@ type Lexer struct {
5959

6060
// FetchToken scans the input for the next token.
6161
func (r *Lexer) FetchToken() {
62-
r.token.kind = tokenUndef
62+
r.token.kind = TokenUndef
6363
r.start = r.pos
6464

6565
// Check if r.Data has r.pos element
@@ -90,7 +90,7 @@ func (r *Lexer) FetchToken() {
9090
r.errSyntax()
9191
}
9292

93-
r.token.kind = tokenString
93+
r.token.kind = TokenString
9494
r.fetchString()
9595
return
9696

@@ -99,7 +99,7 @@ func (r *Lexer) FetchToken() {
9999
r.errSyntax()
100100
}
101101
r.firstElement = true
102-
r.token.kind = tokenDelim
102+
r.token.kind = TokenDelim
103103
r.token.delimValue = r.Data[r.pos]
104104
r.pos++
105105
return
@@ -109,7 +109,7 @@ func (r *Lexer) FetchToken() {
109109
r.errSyntax()
110110
}
111111
r.wantSep = 0
112-
r.token.kind = tokenDelim
112+
r.token.kind = TokenDelim
113113
r.token.delimValue = r.Data[r.pos]
114114
r.pos++
115115
return
@@ -118,7 +118,7 @@ func (r *Lexer) FetchToken() {
118118
if r.wantSep != 0 {
119119
r.errSyntax()
120120
}
121-
r.token.kind = tokenNumber
121+
r.token.kind = TokenNumber
122122
r.fetchNumber()
123123
return
124124

@@ -127,7 +127,7 @@ func (r *Lexer) FetchToken() {
127127
r.errSyntax()
128128
}
129129

130-
r.token.kind = tokenNull
130+
r.token.kind = TokenNull
131131
r.fetchNull()
132132
return
133133

@@ -136,7 +136,7 @@ func (r *Lexer) FetchToken() {
136136
r.errSyntax()
137137
}
138138

139-
r.token.kind = tokenBool
139+
r.token.kind = TokenBool
140140
r.token.boolValue = true
141141
r.fetchTrue()
142142
return
@@ -146,7 +146,7 @@ func (r *Lexer) FetchToken() {
146146
r.errSyntax()
147147
}
148148

149-
r.token.kind = tokenBool
149+
r.token.kind = TokenBool
150150
r.token.boolValue = false
151151
r.fetchFalse()
152152
return
@@ -391,7 +391,7 @@ func (r *Lexer) fetchString() {
391391

392392
// scanToken scans the next token if no token is currently available in the lexer.
393393
func (r *Lexer) scanToken() {
394-
if r.token.kind != tokenUndef || r.fatalError != nil {
394+
if r.token.kind != TokenUndef || r.fatalError != nil {
395395
return
396396
}
397397

@@ -400,7 +400,7 @@ func (r *Lexer) scanToken() {
400400

401401
// consume resets the current token to allow scanning the next one.
402402
func (r *Lexer) consume() {
403-
r.token.kind = tokenUndef
403+
r.token.kind = TokenUndef
404404
r.token.byteValueCloned = false
405405
r.token.delimValue = 0
406406
}
@@ -443,10 +443,10 @@ func (r *Lexer) errInvalidToken(expected string) {
443443
switch expected {
444444
case "[":
445445
r.token.delimValue = ']'
446-
r.token.kind = tokenDelim
446+
r.token.kind = TokenDelim
447447
case "{":
448448
r.token.delimValue = '}'
449-
r.token.kind = tokenDelim
449+
r.token.kind = TokenDelim
450450
}
451451
r.addNonfatalError(&LexerError{
452452
Reason: fmt.Sprintf("expected %s", expected),
@@ -475,7 +475,7 @@ func (r *Lexer) GetPos() int {
475475

476476
// Delim consumes a token and verifies that it is the given delimiter.
477477
func (r *Lexer) Delim(c byte) {
478-
if r.token.kind == tokenUndef && r.Ok() {
478+
if r.token.kind == TokenUndef && r.Ok() {
479479
r.FetchToken()
480480
}
481481

@@ -489,34 +489,34 @@ func (r *Lexer) Delim(c byte) {
489489

490490
// IsDelim returns true if there was no scanning error and next token is the given delimiter.
491491
func (r *Lexer) IsDelim(c byte) bool {
492-
if r.token.kind == tokenUndef && r.Ok() {
492+
if r.token.kind == TokenUndef && r.Ok() {
493493
r.FetchToken()
494494
}
495495
return !r.Ok() || r.token.delimValue == c
496496
}
497497

498498
// Null verifies that the next token is null and consumes it.
499499
func (r *Lexer) Null() {
500-
if r.token.kind == tokenUndef && r.Ok() {
500+
if r.token.kind == TokenUndef && r.Ok() {
501501
r.FetchToken()
502502
}
503-
if !r.Ok() || r.token.kind != tokenNull {
503+
if !r.Ok() || r.token.kind != TokenNull {
504504
r.errInvalidToken("null")
505505
}
506506
r.consume()
507507
}
508508

509509
// IsNull returns true if the next token is a null keyword.
510510
func (r *Lexer) IsNull() bool {
511-
if r.token.kind == tokenUndef && r.Ok() {
511+
if r.token.kind == TokenUndef && r.Ok() {
512512
r.FetchToken()
513513
}
514-
return r.Ok() && r.token.kind == tokenNull
514+
return r.Ok() && r.token.kind == TokenNull
515515
}
516516

517517
// Skip skips a single token.
518518
func (r *Lexer) Skip() {
519-
if r.token.kind == tokenUndef && r.Ok() {
519+
if r.token.kind == TokenUndef && r.Ok() {
520520
r.FetchToken()
521521
}
522522
r.consume()
@@ -621,10 +621,10 @@ func (r *Lexer) Consumed() {
621621
}
622622

623623
func (r *Lexer) unsafeString(skipUnescape bool) (string, []byte) {
624-
if r.token.kind == tokenUndef && r.Ok() {
624+
if r.token.kind == TokenUndef && r.Ok() {
625625
r.FetchToken()
626626
}
627-
if !r.Ok() || r.token.kind != tokenString {
627+
if !r.Ok() || r.token.kind != TokenString {
628628
r.errInvalidToken("string")
629629
return "", nil
630630
}
@@ -664,10 +664,10 @@ func (r *Lexer) UnsafeFieldName(skipUnescape bool) string {
664664

665665
// String reads a string literal.
666666
func (r *Lexer) String() string {
667-
if r.token.kind == tokenUndef && r.Ok() {
667+
if r.token.kind == TokenUndef && r.Ok() {
668668
r.FetchToken()
669669
}
670-
if !r.Ok() || r.token.kind != tokenString {
670+
if !r.Ok() || r.token.kind != TokenString {
671671
r.errInvalidToken("string")
672672
return ""
673673
}
@@ -687,10 +687,10 @@ func (r *Lexer) String() string {
687687

688688
// StringIntern reads a string literal, and performs string interning on it.
689689
func (r *Lexer) StringIntern() string {
690-
if r.token.kind == tokenUndef && r.Ok() {
690+
if r.token.kind == TokenUndef && r.Ok() {
691691
r.FetchToken()
692692
}
693-
if !r.Ok() || r.token.kind != tokenString {
693+
if !r.Ok() || r.token.kind != TokenString {
694694
r.errInvalidToken("string")
695695
return ""
696696
}
@@ -705,10 +705,10 @@ func (r *Lexer) StringIntern() string {
705705

706706
// Bytes reads a string literal and base64 decodes it into a byte slice.
707707
func (r *Lexer) Bytes() []byte {
708-
if r.token.kind == tokenUndef && r.Ok() {
708+
if r.token.kind == TokenUndef && r.Ok() {
709709
r.FetchToken()
710710
}
711-
if !r.Ok() || r.token.kind != tokenString {
711+
if !r.Ok() || r.token.kind != TokenString {
712712
r.errInvalidToken("string")
713713
return nil
714714
}
@@ -731,10 +731,10 @@ func (r *Lexer) Bytes() []byte {
731731

732732
// Bool reads a true or false boolean keyword.
733733
func (r *Lexer) Bool() bool {
734-
if r.token.kind == tokenUndef && r.Ok() {
734+
if r.token.kind == TokenUndef && r.Ok() {
735735
r.FetchToken()
736736
}
737-
if !r.Ok() || r.token.kind != tokenBool {
737+
if !r.Ok() || r.token.kind != TokenBool {
738738
r.errInvalidToken("bool")
739739
return false
740740
}
@@ -744,10 +744,10 @@ func (r *Lexer) Bool() bool {
744744
}
745745

746746
func (r *Lexer) number() string {
747-
if r.token.kind == tokenUndef && r.Ok() {
747+
if r.token.kind == TokenUndef && r.Ok() {
748748
r.FetchToken()
749749
}
750-
if !r.Ok() || r.token.kind != tokenNumber {
750+
if !r.Ok() || r.token.kind != TokenNumber {
751751
r.errInvalidToken("number")
752752
return ""
753753
}
@@ -1151,7 +1151,7 @@ func (r *Lexer) GetNonFatalErrors() []*LexerError {
11511151
// JsonNumber fetches and json.Number from 'encoding/json' package.
11521152
// Both int, float or string, contains them are valid values
11531153
func (r *Lexer) JsonNumber() json.Number {
1154-
if r.token.kind == tokenUndef && r.Ok() {
1154+
if r.token.kind == TokenUndef && r.Ok() {
11551155
r.FetchToken()
11561156
}
11571157
if !r.Ok() {
@@ -1160,11 +1160,11 @@ func (r *Lexer) JsonNumber() json.Number {
11601160
}
11611161

11621162
switch r.token.kind {
1163-
case tokenString:
1163+
case TokenString:
11641164
return json.Number(r.String())
1165-
case tokenNumber:
1165+
case TokenNumber:
11661166
return json.Number(r.Raw())
1167-
case tokenNull:
1167+
case TokenNull:
11681168
r.Null()
11691169
return json.Number("")
11701170
default:
@@ -1175,21 +1175,21 @@ func (r *Lexer) JsonNumber() json.Number {
11751175

11761176
// Interface fetches an interface{} analogous to the 'encoding/json' package.
11771177
func (r *Lexer) Interface() interface{} {
1178-
if r.token.kind == tokenUndef && r.Ok() {
1178+
if r.token.kind == TokenUndef && r.Ok() {
11791179
r.FetchToken()
11801180
}
11811181

11821182
if !r.Ok() {
11831183
return nil
11841184
}
11851185
switch r.token.kind {
1186-
case tokenString:
1186+
case TokenString:
11871187
return r.String()
1188-
case tokenNumber:
1188+
case TokenNumber:
11891189
return r.Float64()
1190-
case tokenBool:
1190+
case TokenBool:
11911191
return r.Bool()
1192-
case tokenNull:
1192+
case TokenNull:
11931193
r.Null()
11941194
return nil
11951195
}
@@ -1242,3 +1242,16 @@ func (r *Lexer) WantColon() {
12421242
r.wantSep = ':'
12431243
r.firstElement = false
12441244
}
1245+
1246+
// CurrentToken returns current token kind if there were no errors and TokenUndef otherwise
1247+
func (r *Lexer) CurrentToken() TokenKind {
1248+
if r.token.kind == TokenUndef && r.Ok() {
1249+
r.FetchToken()
1250+
}
1251+
1252+
if !r.Ok() {
1253+
return TokenUndef
1254+
}
1255+
1256+
return r.token.kind
1257+
}

jlexer/lexer_test.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,3 +373,18 @@ func TestFetchStringUnterminatedString(t *testing.T) {
373373
}
374374
}
375375
}
376+
377+
func TestCurrentToken(t *testing.T) {
378+
data := []byte(`{"foo"`)
379+
tokens := []TokenKind{TokenDelim, TokenString, TokenUndef}
380+
l := Lexer{Data: data}
381+
382+
for _, want := range tokens {
383+
got := l.CurrentToken()
384+
if got != want {
385+
t.Errorf("CurrentToken() = %v; want %v (err %s)", got, want, l.Error())
386+
}
387+
388+
l.Skip()
389+
}
390+
}

0 commit comments

Comments
 (0)