@@ -100,6 +100,18 @@ extension Source {
100
100
}
101
101
}
102
102
103
+ mutating func tryEatNonEmpty( _ c: Char ) throws -> Bool {
104
+ guard !isEmpty else { throw ParseError . expected ( String ( c) ) }
105
+ return tryEat ( c)
106
+ }
107
+
108
+ mutating func tryEatNonEmpty< C: Collection > ( sequence c: C ) throws -> Bool
109
+ where C. Element == Char
110
+ {
111
+ guard !isEmpty else { throw ParseError . expected ( String ( c) ) }
112
+ return tryEat ( sequence: c)
113
+ }
114
+
103
115
/// Throws an expected ASCII character error if not matched
104
116
mutating func expectASCII( ) throws -> Located < Character > {
105
117
try recordLoc { src in
@@ -225,7 +237,7 @@ extension Source {
225
237
// Hex numbers.
226
238
case " u " , " x " :
227
239
if src. tryEat ( " { " ) {
228
- let str = src. lexUntil ( eating: " } " ) . value
240
+ let str = try src. lexUntil ( eating: " } " ) . value
229
241
return try Source . validateUnicodeScalar ( str, . hex)
230
242
}
231
243
let numDigits = base == " u " ? 4 : 2
@@ -235,7 +247,7 @@ extension Source {
235
247
236
248
// Octal numbers.
237
249
case " o " where src. tryEat ( " { " ) :
238
- let str = src. lexUntil ( eating: " } " ) . value
250
+ let str = try src. lexUntil ( eating: " } " ) . value
239
251
return try Source . validateUnicodeScalar ( str, . octal)
240
252
241
253
case " 0 " :
@@ -342,27 +354,33 @@ extension Source {
342
354
}
343
355
344
356
private mutating func lexUntil(
345
- _ predicate: ( inout Source ) -> Bool
346
- ) -> Located < String > {
347
- recordLoc { src in
357
+ _ predicate: ( inout Source ) throws -> Bool
358
+ ) rethrows -> Located < String > {
359
+ try recordLoc { src in
348
360
var result = " "
349
- while !predicate( & src) {
361
+ while try ! predicate( & src) {
350
362
result. append ( src. eat ( ) )
351
363
}
352
364
return result
353
365
}
354
366
}
355
367
356
- private mutating func lexUntil( eating end: String ) -> Located < String > {
357
- lexUntil { $0. tryEat ( sequence: end) }
368
+ private mutating func lexUntil( eating end: String ) throws -> Located < String > {
369
+ try lexUntil { try $0. tryEatNonEmpty ( sequence: end) }
370
+ }
371
+
372
+ private mutating func lexUntil(
373
+ eating end: Character
374
+ ) throws -> Located < String > {
375
+ try lexUntil ( eating: String ( end) )
358
376
}
359
377
360
378
/// Expect a linear run of non-nested non-empty content
361
379
private mutating func expectQuoted(
362
380
endingWith end: String
363
381
) throws -> Located < String > {
364
382
try recordLoc { src in
365
- let result = src. lexUntil ( eating: end) . value
383
+ let result = try src. lexUntil ( eating: end) . value
366
384
guard !result. isEmpty else {
367
385
throw ParseError . misc ( " Expected non-empty contents " )
368
386
}
@@ -586,13 +604,13 @@ extension Source {
586
604
587
605
// We should either have a unicode scalar.
588
606
if src. tryEat ( sequence: " U+ " ) {
589
- let str = src. lexUntil ( eating: " } " ) . value
607
+ let str = try src. lexUntil ( eating: " } " ) . value
590
608
return . scalar( try Source . validateUnicodeScalar ( str, . hex) )
591
609
}
592
610
593
611
// Or we should have a character name.
594
612
// TODO: Validate the types of characters that can appear in the name?
595
- return . namedCharacter( src. lexUntil ( eating: " } " ) . value)
613
+ return . namedCharacter( try src. lexUntil ( eating: " } " ) . value)
596
614
}
597
615
}
598
616
@@ -606,14 +624,15 @@ extension Source {
606
624
// of true), and its key is inferred.
607
625
// TODO: We could have better recovery here if we only ate the characters
608
626
// that property keys and values can use.
609
- let lhs = src. lexUntil { $0. peek ( ) == " = " || $0. starts ( with: end) } . value
610
- if src. tryEat ( sequence: end) {
611
- return try Source . classifyCharacterPropertyValueOnly ( lhs)
612
- }
613
- src. eat ( asserting: " = " )
614
-
615
- let rhs = src. lexUntil ( eating: end) . value
616
- return try Source . classifyCharacterProperty ( key: lhs, value: rhs)
627
+ let lhs = src. lexUntil {
628
+ $0. isEmpty || $0. peek ( ) == " = " || $0. starts ( with: end)
629
+ } . value
630
+ if src. tryEat ( " = " ) {
631
+ let rhs = try src. lexUntil ( eating: end) . value
632
+ return try Source . classifyCharacterProperty ( key: lhs, value: rhs)
633
+ }
634
+ try src. expect ( sequence: end)
635
+ return try Source . classifyCharacterPropertyValueOnly ( lhs)
617
636
}
618
637
}
619
638
0 commit comments