Skip to content

Commit c35c30a

Browse files
author
Tim Vermeulen
authored
Add the CustomRegexComponent protocol (#173)
1 parent f8e1dc2 commit c35c30a

File tree

5 files changed

+22
-35
lines changed

5 files changed

+22
-35
lines changed

Sources/_StringProcessing/Engine/MEProgram.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ public struct MEProgram<Input: Collection> where Input.Element: Equatable {
1818
public typealias TransformFunction =
1919
(Input, Range<Input.Index>) -> Any?
2020
public typealias MatcherFunction =
21-
(Input, Range<Input.Index>) -> (Input.Index, Any)?
21+
(Input, Input.Index, Range<Input.Index>) -> (Input.Index, Any)?
2222

2323
var instructions: InstructionList<Instruction>
2424

Sources/_StringProcessing/Engine/Processor.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,7 @@ extension Processor {
362362
let (matcherReg, valReg) = payload.pairedMatcherValue
363363
let matcher = registers[matcherReg]
364364
guard let (nextIdx, val) = matcher(
365-
input, currentPosition..<bounds.upperBound
365+
input, currentPosition, bounds
366366
) else {
367367
signalFailure()
368368
return

Sources/_StringProcessing/RegexDSL/DSLConsumers.swift

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,24 +9,18 @@
99
//
1010
//===----------------------------------------------------------------------===//
1111

12-
extension MatchingCollectionConsumer where Consumed == String {
13-
public var regex: Regex<Match> {
14-
Regex(node: .matcher(.init(Match.self)) {
15-
self.matchingConsuming($0, in: $1)
16-
})
17-
}
12+
public protocol CustomRegexComponent: RegexProtocol {
13+
func match(
14+
_ input: String,
15+
startingAt index: String.Index,
16+
in bounds: Range<String.Index>
17+
) -> (upperBound: String.Index, match: Match)?
1818
}
1919

20-
extension CollectionConsumer where Consumed == String {
21-
public var regex: Regex<Void> {
22-
Regex(node: .consumer {
23-
self.consuming($0, in: $1)
24-
})
20+
extension CustomRegexComponent {
21+
public var regex: Regex<Match> {
22+
Regex(node: .matcher(.init(Match.self), { input, index, bounds in
23+
match(input, startingAt: index, in: bounds)
24+
}))
2525
}
2626
}
27-
28-
// TODO: How can/should the DSL choose between them? Need to
29-
// know whether value is captured or not. Should this be
30-
// done via how we declare API or should this be part of
31-
// compilation / DSLTree logic?
32-

Sources/_StringProcessing/RegexDSL/DSLTree.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ typealias _ConsumerInterface = (
132132
// Type producing consume
133133
// TODO: better name
134134
typealias _MatcherInterface = (
135-
String, Range<String.Index>
135+
String, String.Index, Range<String.Index>
136136
) -> (String.Index, Any)?
137137

138138
// Character-set (post grapheme segmentation)

Tests/RegexTests/CustomTests.swift

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,21 @@ import _StringProcessing
22
import XCTest
33

44
// A nibbler processes a single character from a string
5-
private protocol Nibbler:
6-
MatchingCollectionConsumer, RegexProtocol
7-
where Consumed == String {
5+
private protocol Nibbler: CustomRegexComponent {
86
func nibble(_: Character) -> Match?
97
}
108

119
extension Nibbler {
1210
// Default implementation, just feed the character in
13-
func matchingConsuming(
14-
_ consumed: Consumed,
15-
in range: Range<Consumed.Index>
16-
) -> (upperBound: Consumed.Index, match: Match)? {
17-
guard !range.isEmpty else {
18-
// FIXME: Do we have a full story here?
11+
func match(
12+
_ input: String,
13+
startingAt index: String.Index,
14+
in bounds: Range<String.Index>
15+
) -> (upperBound: String.Index, match: Match)? {
16+
guard index != bounds.upperBound, let res = nibble(input[index]) else {
1917
return nil
2018
}
21-
let idx = range.lowerBound
22-
23-
guard let res = nibble(consumed[idx]) else {
24-
return nil
25-
}
26-
return (consumed.index(after: idx), res)
19+
return (input.index(after: index), res)
2720
}
2821
}
2922

0 commit comments

Comments
 (0)