@@ -552,47 +552,53 @@ extension Parser {
552552 return nil
553553 }
554554
555+ /// Attempt to parse a custom character class range into `members`, or regular
556+ /// members if a range cannot be formed.
557+ mutating func parsePotentialCCRange(
558+ into members: inout [ CustomCC . Member ]
559+ ) throws {
560+ guard case . atom( let lhs) ? = members. last else { return }
561+
562+ // Try and see if we can parse a character class range. Each time we parse
563+ // a component of the range, we append to `members` in case it ends up not
564+ // being a range, and we bail. If we succeed in parsing, we remove the
565+ // intermediate members.
566+ let membersBeforeRange = members. count - 1
567+ while let t = try source. lexTrivia ( context: context) {
568+ members. append ( . trivia( t) )
569+ }
570+ guard let dash = source. lexCustomCharacterClassRangeOperator ( ) else {
571+ return
572+ }
573+
574+ // If we can't parse a range, '-' becomes literal, e.g `[6-]`.
575+ members. append ( . atom( . init( . char( " - " ) , dash) ) )
576+
577+ while let t = try source. lexTrivia ( context: context) {
578+ members. append ( . trivia( t) )
579+ }
580+ guard let rhs = try parseCCCMember ( ) else { return }
581+ members. append ( rhs)
582+
583+ guard case let . atom( rhs) = rhs else { return }
584+
585+ // We've successfully parsed an atom LHS and RHS, so form a range,
586+ // collecting the trivia we've parsed, and replacing the members that
587+ // would have otherwise been added to the custom character class.
588+ let rangeMemberCount = members. count - membersBeforeRange
589+ let trivia = members. suffix ( rangeMemberCount) . compactMap ( \. asTrivia)
590+ members. removeLast ( rangeMemberCount)
591+ members. append ( . range( . init( lhs, dash, rhs, trivia: trivia) ) )
592+ }
593+
555594 mutating func parseCCCMembers(
556595 into members: inout Array < CustomCC . Member >
557596 ) throws {
558- // Parse members until we see the end of the custom char class or an
559- // operator.
597+ // Parse members and ranges until we see the end of the custom char class
598+ // or an operator.
560599 while let member = try parseCCCMember ( ) {
561600 members. append ( member)
562-
563- // If we have an atom, we can try to parse a character class range. Each
564- // time we parse a component of the range, we append to `members` in case
565- // it ends up not being a range, and we bail. If we succeed in parsing, we
566- // remove the intermediate members.
567- if case . atom( let lhs) = member {
568- let membersBeforeRange = members. count - 1
569-
570- while let t = try source. lexTrivia ( context: context) {
571- members. append ( . trivia( t) )
572- }
573-
574- guard let dash = source. lexCustomCharacterClassRangeOperator ( ) else {
575- continue
576- }
577- // If we can't parse a range, '-' becomes literal, e.g `[6-]`.
578- members. append ( . atom( . init( . char( " - " ) , dash) ) )
579-
580- while let t = try source. lexTrivia ( context: context) {
581- members. append ( . trivia( t) )
582- }
583- guard let rhs = try parseCCCMember ( ) else { continue }
584- members. append ( rhs)
585-
586- guard case let . atom( rhs) = rhs else { continue }
587-
588- // We've successfully parsed an atom LHS and RHS, so form a range,
589- // collecting the trivia we've parsed, and replacing the members that
590- // would have otherwise been added to the custom character class.
591- let rangeMemberCount = members. count - membersBeforeRange
592- let trivia = members. suffix ( rangeMemberCount) . compactMap ( \. asTrivia)
593- members. removeLast ( rangeMemberCount)
594- members. append ( . range( . init( lhs, dash, rhs, trivia: trivia) ) )
595- }
601+ try parsePotentialCCRange ( into: & members)
596602 }
597603 }
598604}
0 commit comments