Section 3 - Handing Multiple Concats - Social Security Numbers

According to Wikipedia a US Social Security number is:

a nine-digit number in the format “AAA-GG-SSSS”. The number is divided into three parts: the first three digits, known as the area number because they were formerly assigned by geographical region; the middle two digits, known as the group number; and the final four digits, known as the serial number.

So let’s build that as a Rope:

import ropes.core._

type Area   = Repeated.Exactly[3, Range['0', '9']]
type Group  = Repeated.Exactly[2, Range['0', '9']]
type Serial = Repeated.Exactly[4, Range['0', '9']]
type Dash   = Literal['-']
type SSN    = Concat[Area, Concat[Dash, Concat[Group, Concat[Dash, Serial]]]]

The Repeated.Exactly[N, R] is just an alias for Repeated which uses the same value for maximum and minimum instances.

To allow multiple concatenations, the nesting must occur on the suffix rather than the prefix.

Using section

We could access parts of the SSN in the same way as we have done previously:

val Right(parsed) = Rope.parseTo[SSN]("078-05-1120")
// parsed: SSN = Concat(
//   prefix = Repeated(
//     values = List(
//       CharacterClass(value = '0'),
//       CharacterClass(value = '7'),
//       CharacterClass(value = '8')
//     )
//   ),
//   suffix = Concat(
//     prefix = Literal(value = '-'),
//     suffix = Concat(
//       prefix = Repeated(
//         values = List(CharacterClass(value = '0'), CharacterClass(value = '5'))
//       ),
//       suffix = Concat(
//         prefix = Literal(value = '-'),
//         suffix = Repeated(
//           values = List(
//             CharacterClass(value = '1'),
//             CharacterClass(value = '1'),
//             CharacterClass(value = '2'),
//             CharacterClass(value = '0')
//           )
//         )
//       )
//     )
//   )
// )
parsed.prefix.write
// res0: String = "078"
parsed.suffix.suffix.prefix.write
// res1: String = "05"
parsed.suffix.suffix.suffix.suffix.write
// res2: String = "1120"

but it is clumsy to navigate through all of the prefixes and suffixes. Instead, we ropes provides the section method to access a given section by index:

parsed.section[1].write
// res3: String = "078"
parsed.section[3].write
// res4: String = "05"
parsed.section[5].write
// res5: String = "1120"