@@ -214,7 +214,7 @@ impl Parser<'_> {
214
214
return Ok ( None ) ;
215
215
} ;
216
216
217
- let mut kind = if self . take_str ( "U+" ) {
217
+ let kind = if self . take_str ( "U+" ) {
218
218
self . parse_unicode ( ) ?
219
219
} else if self . input [ self . index ..]
220
220
. chars ( )
@@ -246,30 +246,13 @@ impl Parser<'_> {
246
246
} else {
247
247
return Ok ( None ) ;
248
248
} ;
249
-
250
- static REPEAT_RE : LazyLock < Regex > =
251
- LazyLock :: new ( || Regex :: new ( r"^ ?(\*\?|\+\?|\?|\*|\+)" ) . unwrap ( ) ) ;
252
- static RANGE_RE : LazyLock < Regex > =
253
- LazyLock :: new ( || Regex :: new ( r"^\{([0-9]+)?\.\.([0-9]+)?\}" ) . unwrap ( ) ) ;
254
- if let Some ( cap) = self . take_re ( & REPEAT_RE ) {
255
- kind = match & cap[ 1 ] {
256
- "?" => ExpressionKind :: Optional ( box_kind ( kind) ) ,
257
- "*" => ExpressionKind :: Repeat ( box_kind ( kind) ) ,
258
- "*?" => ExpressionKind :: RepeatNonGreedy ( box_kind ( kind) ) ,
259
- "+" => ExpressionKind :: RepeatPlus ( box_kind ( kind) ) ,
260
- "+?" => ExpressionKind :: RepeatPlusNonGreedy ( box_kind ( kind) ) ,
261
- s => panic ! ( "unexpected `{s}`" ) ,
262
- } ;
263
- } else if let Some ( cap) = self . take_re ( & RANGE_RE ) {
264
- let a = cap. get ( 1 ) . map ( |m| m. as_str ( ) . parse :: < u32 > ( ) . unwrap ( ) ) ;
265
- let b = cap. get ( 2 ) . map ( |m| m. as_str ( ) . parse :: < u32 > ( ) . unwrap ( ) ) ;
266
- match ( a, b) {
267
- ( Some ( a) , Some ( b) ) if b < a => bail ! ( self , "range {a}..{b} is malformed" ) ,
268
- _ => { }
269
- }
270
- kind = ExpressionKind :: RepeatRange ( box_kind ( kind) , a, b) ;
271
- }
272
-
249
+ let kind = match self . peek ( ) {
250
+ Some ( b'?' ) => self . parse_optional ( kind) ?,
251
+ Some ( b'*' ) => self . parse_repeat ( kind) ?,
252
+ Some ( b'+' ) => self . parse_repeat_plus ( kind) ?,
253
+ Some ( b'{' ) => self . parse_repeat_range ( kind) ?,
254
+ _ => kind,
255
+ } ;
273
256
let suffix = self . parse_suffix ( ) ?;
274
257
let footnote = self . parse_footnote ( ) ?;
275
258
@@ -370,6 +353,52 @@ impl Parser<'_> {
370
353
}
371
354
}
372
355
356
+ /// Parse `?` after expression.
357
+ fn parse_optional ( & mut self , kind : ExpressionKind ) -> Result < ExpressionKind > {
358
+ self . expect ( "?" , "expected `?`" ) ?;
359
+ Ok ( ExpressionKind :: Optional ( box_kind ( kind) ) )
360
+ }
361
+
362
+ /// Parse `*` | `*?` after expression.
363
+ fn parse_repeat ( & mut self , kind : ExpressionKind ) -> Result < ExpressionKind > {
364
+ self . expect ( "*" , "expected `*`" ) ?;
365
+ Ok ( if self . take_str ( "?" ) {
366
+ ExpressionKind :: RepeatNonGreedy ( box_kind ( kind) )
367
+ } else {
368
+ ExpressionKind :: Repeat ( box_kind ( kind) )
369
+ } )
370
+ }
371
+
372
+ /// Parse `+` | `+?` after expression.
373
+ fn parse_repeat_plus ( & mut self , kind : ExpressionKind ) -> Result < ExpressionKind > {
374
+ self . expect ( "+" , "expected `+`" ) ?;
375
+ Ok ( if self . take_str ( "?" ) {
376
+ ExpressionKind :: RepeatPlusNonGreedy ( box_kind ( kind) )
377
+ } else {
378
+ ExpressionKind :: RepeatPlus ( box_kind ( kind) )
379
+ } )
380
+ }
381
+
382
+ /// Parse `{a..}` | `{..b}` | `{a..b}` after expression.
383
+ fn parse_repeat_range ( & mut self , kind : ExpressionKind ) -> Result < ExpressionKind > {
384
+ self . expect ( "{" , "expected `{`" ) ?;
385
+ let a = self . take_while ( & |x| x. is_ascii_digit ( ) ) ;
386
+ let Ok ( a) = ( !a. is_empty ( ) ) . then ( || a. parse :: < u32 > ( ) ) . transpose ( ) else {
387
+ bail ! ( self , "malformed range start" ) ;
388
+ } ;
389
+ self . expect ( ".." , "expected `..`" ) ?;
390
+ let b = self . take_while ( & |x| x. is_ascii_digit ( ) ) ;
391
+ let Ok ( b) = ( !b. is_empty ( ) ) . then ( || b. parse :: < u32 > ( ) ) . transpose ( ) else {
392
+ bail ! ( self , "malformed range end" ) ;
393
+ } ;
394
+ match ( a, b) {
395
+ ( Some ( a) , Some ( b) ) if b < a => bail ! ( self , "range {a}..{b} is malformed" ) ,
396
+ _ => { }
397
+ }
398
+ self . expect ( "}" , "expected `}`" ) ?;
399
+ Ok ( ExpressionKind :: RepeatRange ( box_kind ( kind) , a, b) )
400
+ }
401
+
373
402
fn parse_suffix ( & mut self ) -> Result < Option < String > > {
374
403
if !self . take_str ( " _" ) {
375
404
return Ok ( None ) ;
0 commit comments