@@ -422,8 +422,8 @@ extension Parser {
422
422
return . scalarSequence( . init( scalars, trivia: trivia) )
423
423
}
424
424
425
- /// Eat a scalar off the front, starting from after the
426
- /// backslash and base character (e.g. `\u` or `\x`).
425
+ /// Try to eat a scalar off the front, starting from after the backslash and
426
+ /// base character (e.g. `\u` or `\x`).
427
427
///
428
428
/// UniScalar -> 'u{' UniScalarSequence '}'
429
429
/// | 'u' HexDigit{4}
@@ -433,18 +433,16 @@ extension Parser {
433
433
/// | 'o{' OctalDigit{1...} '}'
434
434
/// | '0' OctalDigit{0...3}
435
435
///
436
- mutating func expectUnicodeScalar(
437
- escapedCharacter base: Character
438
- ) -> AST . Atom . Kind {
439
- recordLoc { p in
436
+ mutating func lexUnicodeScalar( ) -> AST . Atom . Kind ? {
437
+ tryEating { p in
440
438
441
439
func nullScalar( ) -> AST . Atom . Scalar {
442
440
. init( UnicodeScalar ( 0 ) , p. loc ( p. src. currentPosition) )
443
441
}
444
442
445
443
// TODO: PCRE offers a different behavior if PCRE2_ALT_BSUX is set.
446
- switch base {
447
- // Hex numbers.
444
+ switch p . tryEat ( ) {
445
+ // Hex numbers.
448
446
case " u " where p. tryEat ( " { " ) :
449
447
return p. expectUnicodeScalarSequence ( eating: " } " )
450
448
@@ -469,7 +467,7 @@ extension Parser {
469
467
case " U " :
470
468
return . scalar( p. expectUnicodeScalar ( numDigits: 8 ) )
471
469
472
- // Octal numbers.
470
+ // Octal numbers.
473
471
case " o " where p. tryEat ( " { " ) :
474
472
let str = p. lexUntil ( eating: " } " )
475
473
return . scalar( p. validateUnicodeScalar ( str, . octal) )
@@ -485,10 +483,9 @@ extension Parser {
485
483
return . scalar( p. validateUnicodeScalar ( digits, . octal) )
486
484
487
485
default :
488
- p. unreachable ( " Unexpected scalar start " )
489
- return . scalar( nullScalar ( ) )
486
+ return nil
490
487
}
491
- } . value
488
+ }
492
489
}
493
490
494
491
/// Try to consume a quantifier
@@ -1754,6 +1751,11 @@ extension Parser {
1754
1751
return ref
1755
1752
}
1756
1753
1754
+ // Hexadecimal and octal unicode scalars.
1755
+ if let scalar = p. lexUnicodeScalar ( ) {
1756
+ return scalar
1757
+ }
1758
+
1757
1759
guard let charLoc = p. tryEatWithLoc ( ) else {
1758
1760
p. errorAtCurrentPosition ( . expectedEscape)
1759
1761
return . invalid
@@ -1767,14 +1769,6 @@ extension Parser {
1767
1769
return . escaped( builtin)
1768
1770
}
1769
1771
1770
- switch char {
1771
- // Hexadecimal and octal unicode scalars.
1772
- case " u " , " x " , " U " , " o " , " 0 " :
1773
- return p. expectUnicodeScalar ( escapedCharacter: char)
1774
- default :
1775
- break
1776
- }
1777
-
1778
1772
// We only allow unknown escape sequences for non-letter non-number ASCII,
1779
1773
// and non-ASCII whitespace.
1780
1774
// TODO: Once we have fix-its, suggest a `0` prefix for octal `[\7]`.
0 commit comments