mutating func lexAtom()

in Sources/_MatchingEngine/Regex/Parse/LexicalAnalysis.swift [1688:1735]


  mutating func lexAtom(context: ParsingContext) throws -> AST.Atom? {
    let customCC = context.isInCustomCharacterClass
    let kind: Located<AST.Atom.Kind>? = try recordLoc { src in
      // Check for not-an-atom, e.g. parser recursion termination
      if src.isEmpty { return nil }
      if !customCC && (src.peek() == ")" || src.peek() == "|") { return nil }
      // TODO: Store customCC in the atom, if that's useful

      // POSIX character property. This is only allowed in a custom character
      // class.
      // TODO: Can we try and recover and diagnose these outside character
      // classes?
      if customCC, let prop = try src.lexPOSIXCharacterProperty()?.value {
        return .property(prop)
      }

      // If we have group syntax that was skipped over in lexGroupStart, we
      // need to handle it as an atom, or throw an error.
      if !customCC && src.shouldLexGroupLikeAtom() {
        return try src.expectGroupLikeAtom()
      }

      let char = src.eat()
      switch char {
      case ")", "|":
        if customCC {
          return .char(char)
        }
        fatalError("unreachable")

      // (sometimes) special metacharacters
      case ".": return customCC ? .char(".") : .any
      case "^": return customCC ? .char("^") : .startOfLine
      case "$": return customCC ? .char("$") : .endOfLine

      // Escaped
      case "\\": return try src.expectEscaped(context: context).value

      case "]":
        assert(!customCC, "parser should have prevented this")
        fallthrough

      default: return .char(char)
      }
    }
    guard let kind = kind else { return nil }
    return AST.Atom(kind.value, kind.location)
  }