diff --git a/Documentation/Evolution/ProposalOverview.md b/Documentation/Evolution/ProposalOverview.md index 898e0db20..7656526a6 100644 --- a/Documentation/Evolution/ProposalOverview.md +++ b/Documentation/Evolution/ProposalOverview.md @@ -39,7 +39,7 @@ Covers the "interior" syntax, extended syntaxes, run-time construction of a rege Proposes a slew of Regex-powered algorithms. -Introduces `CustomPrefixMatchRegexComponent`, which is a monadic-parser style interface for external parsers to be used as components of a regex. +Introduces `CustomConsumingRegexComponent`, which is a monadic-parser style interface for external parsers to be used as components of a regex. ## Unicode for String Processing diff --git a/Documentation/Evolution/RegexTypeOverview.md b/Documentation/Evolution/RegexTypeOverview.md index 68dd6ccc7..94230d724 100644 --- a/Documentation/Evolution/RegexTypeOverview.md +++ b/Documentation/Evolution/RegexTypeOverview.md @@ -231,7 +231,7 @@ The result builder allows for inline failable value construction, which particip Swift regexes describe an unambiguous algorithm, where choice is ordered and effects can be reliably observed. For example, a `print()` statement inside the `TryCapture`'s transform function will run whenever the overall algorithm naturally dictates an attempt should be made. Optimizations can only elide such calls if they can prove it is behavior-preserving (e.g. "pure"). -`CustomPrefixMatchRegexComponent`, discussed in [String Processing Algorithms][pitches], allows industrial-strength parsers to be used a regex components. This allows us to drop the overly-permissive pre-parsing step: +`CustomConsumingRegexComponent`, discussed in [String Processing Algorithms][pitches], allows industrial-strength parsers to be used a regex components. This allows us to drop the overly-permissive pre-parsing step: ```swift func processEntry(_ line: String) -> Transaction? { @@ -431,7 +431,7 @@ Regular expressions have a deservedly mixed reputation, owing to their historica * "Regular expressions are bad because you should use a real parser" - In other systems, you're either in or you're out, leading to a gravitational pull to stay in when... you should get out - - Our remedy is interoperability with real parsers via `CustomPrefixMatchRegexComponent` + - Our remedy is interoperability with real parsers via `CustomConsumingRegexComponent` - Literals with refactoring actions provide an incremental off-ramp from regex syntax to result builders and real parsers * "Regular expressions are bad because ugly unmaintainable syntax" - We propose literals with source tools support, allowing for better syntax highlighting and analysis @@ -516,7 +516,7 @@ Regex are compiled into an intermediary representation and fairly simple analysi ### Future work: parser combinators -What we propose here is an incremental step towards better parsing support in Swift using parser-combinator style libraries. The underlying execution engine supports recursive function calls and mechanisms for library extensibility. `CustomPrefixMatchRegexComponent`'s protocol requirement is effectively a [monadic parser](https://homepages.inf.ed.ac.uk/wadler/papers/marktoberdorf/baastad.pdf), meaning `Regex` provides a regex-flavored combinator-like system. +What we propose here is an incremental step towards better parsing support in Swift using parser-combinator style libraries. The underlying execution engine supports recursive function calls and mechanisms for library extensibility. `CustomConsumingRegexComponent`'s protocol requirement is effectively a [monadic parser](https://homepages.inf.ed.ac.uk/wadler/papers/marktoberdorf/baastad.pdf), meaning `Regex` provides a regex-flavored combinator-like system. An issues with traditional parser combinator libraries are the compilation barriers between call-site and definition, resulting in excessive and overly-cautious backtracking traffic. These can be eliminated through better [compilation techniques](https://core.ac.uk/download/pdf/148008325.pdf). As mentioned above, Swift's support for custom static compilation is still under development. @@ -565,7 +565,7 @@ Regexes are often used for tokenization and tokens can be represented with Swift ### Future work: baked-in localized processing -- `CustomPrefixMatchRegexComponent` gives an entry point for localized processors +- `CustomConsumingRegexComponent` gives an entry point for localized processors - Future work includes (sub?)protocols to communicate localization intent --> diff --git a/Documentation/Evolution/StringProcessingAlgorithms.md b/Documentation/Evolution/StringProcessingAlgorithms.md index edefbd19b..263c00d3b 100644 --- a/Documentation/Evolution/StringProcessingAlgorithms.md +++ b/Documentation/Evolution/StringProcessingAlgorithms.md @@ -8,7 +8,7 @@ We propose: 1. New regex-powered algorithms over strings, bringing the standard library up to parity with scripting languages 2. Generic `Collection` equivalents of these algorithms in terms of subsequences -3. `protocol CustomPrefixMatchRegexComponent`, which allows 3rd party libraries to provide their industrial-strength parsers as intermixable components of regexes +3. `protocol CustomConsumingRegexComponent`, which allows 3rd party libraries to provide their industrial-strength parsers as intermixable components of regexes This proposal is part of a larger [regex-powered string processing initiative](https://github.com/apple/swift-evolution/blob/main/proposals/0350-regex-type-overview.md), the status of each proposal is tracked [here](https://github.com/apple/swift-experimental-string-processing/blob/main/Documentation/Evolution/ProposalOverview.md). Further discussion of regex specifics is out of scope of this proposal and better discussed in their relevant reviews. @@ -132,7 +132,7 @@ Parsing a currency string such as `$3,020.85` with regex is also tricky, as it c ### Complex string processing -We propose a `CustomPrefixMatchRegexComponent` protocol which allows types from outside the standard library participate in regex builders and `RegexComponent` algorithms. This allows types, such as `Date.ParseStrategy` and `FloatingPointFormatStyle.Currency`, to be used directly within a regex: +We propose a `CustomConsumingRegexComponent` protocol which allows types from outside the standard library participate in regex builders and `RegexComponent` algorithms. This allows types, such as `Date.ParseStrategy` and `FloatingPointFormatStyle.Currency`, to be used directly within a regex: ```swift let dateRegex = Regex { @@ -169,14 +169,14 @@ We also propose the following regex-powered algorithms as well as their generic ## Detailed design -### `CustomPrefixMatchRegexComponent` +### `CustomConsumingRegexComponent` -`CustomPrefixMatchRegexComponent` inherits from `RegexComponent` and satisfies its sole requirement. Conformers can be used with all of the string algorithms generic over `RegexComponent`. +`CustomConsumingRegexComponent` inherits from `RegexComponent` and satisfies its sole requirement. Conformers can be used with all of the string algorithms generic over `RegexComponent`. ```swift /// A protocol allowing custom types to function as regex components by /// providing the raw functionality backing `prefixMatch`. -public protocol CustomPrefixMatchRegexComponent: RegexComponent { +public protocol CustomConsumingRegexComponent: RegexComponent { /// Process the input string within the specified bounds, beginning at the given index, and return /// the end position (upper bound) of the match and the produced output. /// - Parameters: @@ -199,7 +199,7 @@ public protocol CustomPrefixMatchRegexComponent: RegexComponent { We use Foundation `FloatingPointFormatStyle.Currency` as an example for protocol conformance. It would implement the `match` function with `Match` being a `Decimal`. It could also add a static function `.localizedCurrency(code:)` as a member of `RegexComponent`, so it can be referred as `.localizedCurrency(code:)` in the `Regex` result builder: ```swift -extension FloatingPointFormatStyle.Currency : CustomPrefixMatchRegexComponent { +extension FloatingPointFormatStyle.Currency : CustomConsumingRegexComponent { public func consuming( _ input: String, startingAt index: String.Index, diff --git a/Sources/_StringProcessing/Regex/CustomComponents.swift b/Sources/_StringProcessing/Regex/CustomComponents.swift index e8111555c..d675c3ae7 100644 --- a/Sources/_StringProcessing/Regex/CustomComponents.swift +++ b/Sources/_StringProcessing/Regex/CustomComponents.swift @@ -12,7 +12,7 @@ @available(SwiftStdlib 5.7, *) /// A protocol allowing custom types to function as regex components by /// providing the raw functionality backing `prefixMatch`. -public protocol CustomPrefixMatchRegexComponent: RegexComponent { +public protocol CustomConsumingRegexComponent: RegexComponent { /// Process the input string within the specified bounds, beginning at the given index, and return /// the end position (upper bound) of the match and the produced output. /// - Parameters: @@ -29,7 +29,7 @@ public protocol CustomPrefixMatchRegexComponent: RegexComponent { } @available(SwiftStdlib 5.7, *) -extension CustomPrefixMatchRegexComponent { +extension CustomConsumingRegexComponent { public var regex: Regex { let node: DSLTree.Node = .matcher(RegexOutput.self, { input, index, bounds in try consuming(input, startingAt: index, in: bounds) diff --git a/Tests/RegexBuilderTests/CustomTests.swift b/Tests/RegexBuilderTests/CustomTests.swift index 269f9ebaa..bc71f2363 100644 --- a/Tests/RegexBuilderTests/CustomTests.swift +++ b/Tests/RegexBuilderTests/CustomTests.swift @@ -14,7 +14,7 @@ import _StringProcessing @testable import RegexBuilder // A nibbler processes a single character from a string -private protocol Nibbler: CustomPrefixMatchRegexComponent { +private protocol Nibbler: CustomConsumingRegexComponent { func nibble(_: Character) -> RegexOutput? } @@ -49,7 +49,7 @@ private struct Asciibbler: Nibbler { } } -private struct IntParser: CustomPrefixMatchRegexComponent { +private struct IntParser: CustomConsumingRegexComponent { struct ParseError: Error, Hashable {} typealias RegexOutput = Int func consuming(_ input: String, @@ -71,7 +71,7 @@ private struct IntParser: CustomPrefixMatchRegexComponent { } } -private struct CurrencyParser: CustomPrefixMatchRegexComponent { +private struct CurrencyParser: CustomConsumingRegexComponent { enum Currency: String, Hashable { case usd = "USD" case ntd = "NTD" diff --git a/Tests/RegexBuilderTests/RegexDSLTests.swift b/Tests/RegexBuilderTests/RegexDSLTests.swift index cd1c94657..7c06fd6c3 100644 --- a/Tests/RegexBuilderTests/RegexDSLTests.swift +++ b/Tests/RegexBuilderTests/RegexDSLTests.swift @@ -863,7 +863,7 @@ class RegexDSLTests: XCTestCase { var patch: Int var dev: String? } - struct SemanticVersionParser: CustomPrefixMatchRegexComponent { + struct SemanticVersionParser: CustomConsumingRegexComponent { typealias RegexOutput = SemanticVersion func consuming( _ input: String,