@@ -186,31 +186,31 @@ export function parse(str: string, options: ParseOptions = {}): TokenData {
186186 const { encodePath = NOOP_VALUE } = options ;
187187 const chars = [ ...str ] ;
188188 const tokens : Array < LexToken > = [ ] ;
189- let i = 0 ;
190189 let index = 0 ;
190+ let pos = 0 ;
191191
192192 function name ( ) {
193193 let value = "" ;
194194
195- if ( ID_START . test ( chars [ ++ i ] ) ) {
196- value += chars [ i ] ;
197- while ( ID_CONTINUE . test ( chars [ ++ i ] ) ) {
198- value += chars [ i ] ;
195+ if ( ID_START . test ( chars [ index ] ) ) {
196+ value += chars [ index ] ;
197+ while ( ID_CONTINUE . test ( chars [ ++ index ] ) ) {
198+ value += chars [ index ] ;
199199 }
200- } else if ( chars [ i ] === '"' ) {
201- let pos = i ;
200+ } else if ( chars [ index ] === '"' ) {
201+ let pos = index ;
202202
203- while ( i < chars . length ) {
204- if ( chars [ ++ i ] === '"' ) {
205- i ++ ;
203+ while ( index < chars . length ) {
204+ if ( chars [ ++ index ] === '"' ) {
205+ index ++ ;
206206 pos = 0 ;
207207 break ;
208208 }
209209
210- if ( chars [ i ] === "\\" ) {
211- value += chars [ ++ i ] ;
210+ if ( chars [ index ] === "\\" ) {
211+ value += chars [ ++ index ] ;
212212 } else {
213- value += chars [ i ] ;
213+ value += chars [ index ] ;
214214 }
215215 }
216216
@@ -223,103 +223,84 @@ export function parse(str: string, options: ParseOptions = {}): TokenData {
223223
224224 if ( ! value ) {
225225 throw new TypeError (
226- errorMessage ( `Missing parameter name at index ${ i } ` , str ) ,
226+ errorMessage ( `Missing parameter name at index ${ index } ` , str ) ,
227227 ) ;
228228 }
229229
230230 return value ;
231231 }
232232
233- while ( i < chars . length ) {
234- const value = chars [ i ] ;
233+ while ( index < chars . length ) {
234+ const value = chars [ index ] ;
235235 const type = SIMPLE_TOKENS [ value ] ;
236236
237237 if ( type ) {
238- tokens . push ( { type, index : i ++ , value } ) ;
238+ tokens . push ( { type, index : index ++ , value } ) ;
239239 } else if ( value === "\\" ) {
240- tokens . push ( { type : "ESCAPED" , index : i ++ , value : chars [ i ++ ] } ) ;
240+ tokens . push ( { type : "ESCAPED" , index : index ++ , value : chars [ index ++ ] } ) ;
241241 } else if ( value === ":" ) {
242- const value = name ( ) ;
243- tokens . push ( { type : "PARAM" , index : i , value } ) ;
242+ tokens . push ( { type : "PARAM" , index : index ++ , value : name ( ) } ) ;
244243 } else if ( value === "*" ) {
245- const value = name ( ) ;
246- tokens . push ( { type : "WILDCARD" , index : i , value } ) ;
244+ tokens . push ( { type : "WILDCARD" , index : index ++ , value : name ( ) } ) ;
247245 } else {
248- tokens . push ( { type : "CHAR" , index : i , value : chars [ i ++ ] } ) ;
246+ tokens . push ( { type : "CHAR" , index : index ++ , value } ) ;
249247 }
250248 }
251249
252- tokens . push ( { type : "END" , index : i , value : "" } ) ;
253-
254- function peek ( ) : LexToken {
255- return tokens [ index ] ;
256- }
257-
258- function tryConsume ( type : TokenType ) : string | undefined {
259- const token = peek ( ) ;
260- if ( token . type !== type ) return ;
261- index ++ ;
262- return token . value ;
263- }
264-
265- function consume ( type : TokenType ) : string {
266- const value = tryConsume ( type ) ;
267- if ( value !== undefined ) return value ;
268- const { type : nextType , index } = peek ( ) ;
269- throw new TypeError (
270- errorMessage (
271- `Unexpected ${ nextType } at index ${ index } , expected ${ type } ` ,
272- str ,
273- ) ,
274- ) ;
275- }
276-
277- function text ( ) : string {
278- let result = "" ;
279- let value : string | undefined ;
280- while ( ( value = tryConsume ( "CHAR" ) || tryConsume ( "ESCAPED" ) ) ) {
281- result += value ;
282- }
283- return result ;
284- }
250+ tokens . push ( { type : "END" , index, value : "" } ) ;
285251
286252 function consumeUntil ( endType : TokenType ) : Token [ ] {
287- const tokens : Token [ ] = [ ] ;
253+ const output : Token [ ] = [ ] ;
288254
289255 while ( true ) {
290- const path = text ( ) ;
291- if ( path ) tokens . push ( { type : "text" , value : encodePath ( path ) } ) ;
256+ const { type, value, index } = tokens [ pos ++ ] ;
257+ if ( type === endType ) break ;
258+
259+ if ( type === "CHAR" || type === "ESCAPED" ) {
260+ let path = value ;
261+ while ( true ) {
262+ const next = tokens [ pos ] ;
263+ if ( next . type !== "CHAR" && next . type !== "ESCAPED" ) break ;
264+ pos ++ ;
265+ path += next . value ;
266+ }
267+ output . push ( { type : "text" , value : encodePath ( path ) } ) ;
268+ continue ;
269+ }
292270
293- const param = tryConsume ( "PARAM" ) ;
294- if ( param ) {
295- tokens . push ( {
271+ if ( type === "PARAM" ) {
272+ output . push ( {
296273 type : "param" ,
297- name : param ,
274+ name : value ,
298275 } ) ;
299276 continue ;
300277 }
301278
302- const wildcard = tryConsume ( "WILDCARD" ) ;
303- if ( wildcard ) {
304- tokens . push ( {
279+ if ( type === "WILDCARD" ) {
280+ output . push ( {
305281 type : "wildcard" ,
306- name : wildcard ,
282+ name : value ,
307283 } ) ;
308284 continue ;
309285 }
310286
311- const open = tryConsume ( "{" ) ;
312- if ( open ) {
313- tokens . push ( {
287+ if ( type === "{" ) {
288+ output . push ( {
314289 type : "group" ,
315290 tokens : consumeUntil ( "}" ) ,
316291 } ) ;
317292 continue ;
318293 }
319294
320- consume ( endType ) ;
321- return tokens ;
295+ throw new TypeError (
296+ errorMessage (
297+ `Unexpected ${ type } at index ${ index } , expected ${ endType } ` ,
298+ str ,
299+ ) ,
300+ ) ;
322301 }
302+
303+ return output ;
323304 }
324305
325306 return new TokenData ( consumeUntil ( "END" ) , str ) ;
0 commit comments