@@ -68,13 +68,14 @@ class Parser {
68
68
exitLoop: while true {
69
69
let pair = try parseKeyValuePair ( )
70
70
pairs [ pair. key] = pair. value
71
- switch self . advance ( ) {
71
+ let token = self . advance ( )
72
+ switch token {
72
73
case . rightBrace:
73
74
break exitLoop
74
75
case . comma:
75
76
break
76
77
default :
77
- throw JMESPathError . compileTime ( " Expected '}' or ',' " )
78
+ throw JMESPathError . compileTime ( " Expected '}' or ',', not a ' \( token ) ' " )
78
79
}
79
80
}
80
81
return . multiHash( elements: pairs)
@@ -92,21 +93,23 @@ class Parser {
92
93
93
94
case . leftParenthesis:
94
95
let result = try expression ( rbp: 0 )
95
- switch self . advance ( ) {
96
+ let token = self . advance ( )
97
+ switch token {
96
98
case . rightParenthesis:
97
99
return result
98
100
default :
99
- throw JMESPathError . compileTime ( " Expected ')' to close '(' " )
101
+ throw JMESPathError . compileTime ( " Expected ')' to close '(', not a ' \( token ) ' " )
100
102
}
101
103
102
104
default :
103
- throw JMESPathError . compileTime ( " Unexpected token " )
105
+ throw JMESPathError . compileTime ( " Unexpected token ' \( token ) ' " )
104
106
}
105
107
}
106
108
107
109
/// left denotation, tail handler function
108
110
func led( left: Ast ) throws -> Ast {
109
- switch self . advance ( ) {
111
+ let token = self . advance ( )
112
+ switch token {
110
113
case . dot:
111
114
if self . peek ( ) == . star {
112
115
self . advance ( )
@@ -118,13 +121,14 @@ class Parser {
118
121
119
122
case . leftBracket:
120
123
var isNumber : Bool
121
- switch self . peek ( ) {
124
+ let token = self . peek ( )
125
+ switch token {
122
126
case . number, . colon:
123
127
isNumber = true
124
128
case . star:
125
129
isNumber = false
126
130
default :
127
- throw JMESPathError . compileTime ( " Expected number, ':' or '*' " )
131
+ throw JMESPathError . compileTime ( " Expected number, ':' or '*', not a ' \( token ) ' " )
128
132
}
129
133
if isNumber {
130
134
return . subExpr( lhs: left, rhs: try self . parseIndex ( ) )
@@ -150,7 +154,7 @@ class Parser {
150
154
case . field( let name) :
151
155
return . function( name: name, args: try self . parseList ( closing: . rightParenthesis) )
152
156
default :
153
- throw JMESPathError . compileTime ( " Invalid function name " )
157
+ throw JMESPathError . compileTime ( " Invalid function name ' \( left ) ' " )
154
158
}
155
159
156
160
case . flatten:
@@ -173,34 +177,37 @@ class Parser {
173
177
return try self . parseComparator ( Comparator . greaterThanOrEqual, lhs: left)
174
178
175
179
default :
176
- throw JMESPathError . compileTime ( " Unexpected token " )
180
+ throw JMESPathError . compileTime ( " Unexpected token ' \( token ) ' " )
177
181
}
178
182
}
179
183
180
184
/// key : value
181
185
func parseKeyValuePair( ) throws -> ( key: String , value: Ast ) {
182
- switch self . advance ( ) {
186
+ let token = self . advance ( )
187
+ switch token {
183
188
case . identifier( let value) , . quotedIdentifier( let value) :
184
- if self . peek ( ) == . colon {
189
+ let token2 = self . peek ( )
190
+ if token2 == . colon {
185
191
self . advance ( )
186
192
return ( key: value, value: try self . expression ( rbp: 0 ) )
187
193
} else {
188
- throw JMESPathError . compileTime ( " Expected a ':' to follow key " )
194
+ throw JMESPathError . compileTime ( " Expected a ':' to follow key, not a ' \( token2 ) ' " )
189
195
}
190
196
default :
191
- throw JMESPathError . compileTime ( " Expected field to start key value pair " )
197
+ throw JMESPathError . compileTime ( " Expected field to start key value pair, not a ' \( token ) ' " )
192
198
}
193
199
}
194
200
195
201
/// [?...]
196
202
func parseFilter( lhs: Ast ) throws -> Ast {
197
203
let conditionLHS = try self . expression ( rbp: 0 )
198
- switch self . advance ( ) {
204
+ let token = self . advance ( )
205
+ switch token {
199
206
case . rightBracket:
200
207
let conditionRHS = try projectionRHS ( lbp: Token . filter. lbp)
201
208
return . projection( lhs: lhs, rhs: . condition( predicate: conditionLHS, then: conditionRHS) )
202
209
default :
203
- throw JMESPathError . compileTime ( " Expected a ']' to end filter " )
210
+ throw JMESPathError . compileTime ( " Expected a ']' to end filter, not ' \( token ) ' " )
204
211
}
205
212
}
206
213
@@ -221,13 +228,14 @@ class Parser {
221
228
222
229
func parseDot( lbp: Int ) throws -> Ast {
223
230
let isMultiList : Bool
224
- switch self . peek ( ) {
231
+ let token = self . peek ( )
232
+ switch token {
225
233
case . leftBracket:
226
234
isMultiList = true
227
235
case . identifier, . quotedIdentifier, . star, . leftBrace, . ampersand:
228
236
isMultiList = false
229
237
default :
230
- throw JMESPathError . compileTime ( " Expected identifier, '*', '{', '[', '&', or '[?' " )
238
+ throw JMESPathError . compileTime ( " Expected identifier, '*', '{', '[', '&', or '[?', not ' \( token ) ' " )
231
239
}
232
240
if isMultiList {
233
241
self . advance ( )
@@ -249,7 +257,7 @@ class Parser {
249
257
case ( _, 0 ..< projectionStop) :
250
258
return . identity
251
259
default :
252
- throw JMESPathError . compileTime ( " Expected '.', '[', or '[?' " )
260
+ throw JMESPathError . compileTime ( " Expected '.', '[', or '[?', not ' \( token ) ' " )
253
261
}
254
262
if isDot {
255
263
self . advance ( )
@@ -260,12 +268,13 @@ class Parser {
260
268
}
261
269
262
270
func parseWildcardIndex( lhs: Ast ) throws -> Ast {
263
- switch self . advance ( ) {
271
+ let token = self . advance ( )
272
+ switch token {
264
273
case . rightBracket:
265
274
let rhs = try projectionRHS ( lbp: Token . star. lbp)
266
275
return . projection( lhs: lhs, rhs: rhs)
267
276
default :
268
- throw JMESPathError . compileTime ( " Expected ']' after wildcard index " )
277
+ throw JMESPathError . compileTime ( " Expected ']' after wildcard index, not ' \( token ) ' " )
269
278
}
270
279
}
271
280
@@ -287,7 +296,7 @@ class Parser {
287
296
if self . peek ( ) == . comma {
288
297
self . advance ( )
289
298
if self . peek ( ) == closing {
290
- throw JMESPathError . compileTime ( " Invalid token after ',' " )
299
+ throw JMESPathError . compileTime ( " Invalid token ' \( self . peek ( ) ) ' after ','" )
291
300
}
292
301
}
293
302
}
@@ -300,14 +309,15 @@ class Parser {
300
309
var parts : [ Int ? ] = [ nil , nil , nil ]
301
310
var index = 0
302
311
exitLoop: while true {
303
- switch self . advance ( ) {
312
+ let token = self . advance ( )
313
+ switch token {
304
314
case . number( let value) :
305
315
parts [ index] = value
306
316
switch self . peek ( ) {
307
317
case . colon, . rightBracket:
308
318
break
309
319
default :
310
- throw JMESPathError . compileTime ( " Expected ':' or ']' after index " )
320
+ throw JMESPathError . compileTime ( " Expected ':' or ']' after index, not ' \( self . peek ( ) ) ' " )
311
321
}
312
322
313
323
case . rightBracket:
@@ -322,19 +332,19 @@ class Parser {
322
332
case . number, . colon, . rightBracket:
323
333
break
324
334
default :
325
- throw JMESPathError . compileTime ( " Expected number, ':' or ']' " )
335
+ throw JMESPathError . compileTime ( " Expected number, ':' or ']', not ' \( self . peek ( ) ) ' " )
326
336
}
327
337
328
338
default :
329
- throw JMESPathError . compileTime ( " Expected number, ':' or ']' " )
339
+ throw JMESPathError . compileTime ( " Expected number, ':' or ']', not ' \( token ) ' " )
330
340
}
331
341
}
332
342
333
343
if index == 0 {
334
344
if let part = parts [ 0 ] {
335
345
return . index( index: part)
336
346
} else {
337
- throw JMESPathError . compileTime ( " Expected number " )
347
+ throw JMESPathError . compileTime ( " Expected a number " )
338
348
}
339
349
} else {
340
350
let step = parts [ 2 ] ?? 1
0 commit comments