Skip to content

Commit

Permalink
Model reverse as an option
Browse files Browse the repository at this point in the history
  • Loading branch information
Jacob Hearst committed Dec 26, 2024
1 parent 9ed4ba1 commit 00bbc12
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 5 deletions.
3 changes: 3 additions & 0 deletions Sources/_RegexParser/Regex/AST/MatchingOptions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ extension AST {

// NSRegularExpression compatibility special-case
case nsreCompatibleDot // no AST representation

// Lookbehind support
case reverse // no AST representation
}

public var kind: Kind
Expand Down
2 changes: 1 addition & 1 deletion Sources/_RegexParser/Regex/Parse/Sema.swift
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ extension RegexValidator {
case .caseInsensitive, .possessiveByDefault, .reluctantByDefault,
.singleLine, .multiline, .namedCapturesOnly, .extended, .extraExtended,
.asciiOnlyDigit, .asciiOnlyWord, .asciiOnlySpace, .asciiOnlyPOSIXProps,
.nsreCompatibleDot:
.nsreCompatibleDot, .reverse:
break
}
}
Expand Down
12 changes: 8 additions & 4 deletions Sources/_StringProcessing/ByteCodeGen.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ internal import _RegexParser

extension Compiler {
struct ByteCodeGen {
var reverse = false
var reverse: Bool {
options.reversed
}
var options: MatchingOptions
var builder = MEProgram.Builder()
/// A Boolean indicating whether the first matchable atom has been emitted.
Expand Down Expand Up @@ -392,14 +394,16 @@ fileprivate extension Compiler.ByteCodeGen {
throw Unsupported("Lookarounds with custom consumers")
}

let previousReverse = reverse
reverse = !kind.forwards
defer { options.endScope() }
options.beginScope()
// TODO: JH - Is it okay to use .fake here?
options.apply(.init(adding: [.init(.reverse, location: .fake)]))

if kind.positive {
try emitPositiveLookaround(child)
} else {
try emitNegativeLookaround(child)
}
reverse = previousReverse
}

mutating func emitAtomicNoncapturingGroup(
Expand Down
3 changes: 3 additions & 0 deletions Sources/_StringProcessing/LiteralPrinter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,9 @@ extension AST.MatchingOption.Kind {
// NSRE Compatibility option; no literal representation
case .nsreCompatibleDot: return nil

// Reverse option for lookbehinds; no literal representation
case .reverse: return nil

#if RESILIENT_LIBRARIES
@unknown default:
fatalError()
Expand Down
9 changes: 9 additions & 0 deletions Sources/_StringProcessing/MatchingOptions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,10 @@ extension MatchingOptions {
var usesNSRECompatibleDot: Bool {
stack.last!.contains(.nsreCompatibleDot)
}

var reversed: Bool {
stack.last!.contains(.reverse)
}
}

// MARK: - Implementation
Expand All @@ -152,6 +156,9 @@ extension MatchingOptions {
case withoutAnchoringBounds
case nsreCompatibleDot

// Not available via regex literal flags
case reverse

// Oniguruma options
case asciiOnlyDigit
case asciiOnlyPOSIXProps
Expand Down Expand Up @@ -217,6 +224,8 @@ extension MatchingOptions {
self = .extended
case .extraExtended:
self = .extraExtended
case .reverse:
self = .reverse
#if RESILIENT_LIBRARIES
@unknown default:
fatalError()
Expand Down

0 comments on commit 00bbc12

Please sign in to comment.