diff --git a/Sources/Parsing/Builders/ParserBuilder.swift b/Sources/Parsing/Builders/ParserBuilder.swift
index b97b5289de..257d06804e 100644
--- a/Sources/Parsing/Builders/ParserBuilder.swift
+++ b/Sources/Parsing/Builders/ParserBuilder.swift
@@ -127,90 +127,28 @@ public enum ParserBuilder {
where P0.Input == Input, P1.Input == Input {
.init(accumulated, next)
}
-
+
@inlinable
public static func buildPartialBlock(accumulated: P0, next: P1) -> SkipSecond
where P0.Input == Input, P1.Input == Input {
.init(accumulated, next)
}
-
- @_disfavoredOverload
- @inlinable
- public static func buildPartialBlock(accumulated: P0, next: P1) -> Take2
- where P0.Input == Input, P1.Input == Input {
- .init(accumulated, next)
- }
-
- @_disfavoredOverload
- @inlinable
- public static func buildPartialBlock(
- accumulated: P0, next: P1
- ) -> Take3
- where P0.Input == Input, P1.Input == Input {
- .init(accumulated, next)
- }
-
- @_disfavoredOverload
- @inlinable
- public static func buildPartialBlock(
- accumulated: P0, next: P1
- ) -> Take4
- where P0.Input == Input, P1.Input == Input {
- .init(accumulated, next)
- }
-
- @_disfavoredOverload
- @inlinable
- public static func buildPartialBlock(
- accumulated: P0, next: P1
- ) -> Take5
- where P0.Input == Input, P1.Input == Input {
- .init(accumulated, next)
- }
-
- @_disfavoredOverload
- @inlinable
- public static func buildPartialBlock(
- accumulated: P0, next: P1
- ) -> Take6
- where P0.Input == Input, P1.Input == Input {
- .init(accumulated, next)
- }
-
- @_disfavoredOverload
- @inlinable
- public static func buildPartialBlock(
- accumulated: P0, next: P1
- ) -> Take7
- where P0.Input == Input, P1.Input == Input {
- .init(accumulated, next)
- }
-
- @_disfavoredOverload
- @inlinable
- public static func buildPartialBlock(
- accumulated: P0, next: P1
- ) -> Take8
- where P0.Input == Input, P1.Input == Input {
- .init(accumulated, next)
- }
-
- @_disfavoredOverload
- @inlinable
- public static func buildPartialBlock(
- accumulated: P0, next: P1
- ) -> Take9
- where P0.Input == Input, P1.Input == Input {
- .init(accumulated, next)
- }
-
+
@_disfavoredOverload
- @inlinable
- public static func buildPartialBlock(
- accumulated: P0, next: P1
- ) -> Take10
- where P0.Input == Input, P1.Input == Input {
- .init(accumulated, next)
+ public static func buildPartialBlock(
+ accumulated: P0,
+ next: P1
+ ) -> Take2.Map<(repeat each O1, O2)>
+ where
+ P0.Input == Input,
+ P1.Input == Input,
+ P0.Output == (repeat each O1),
+ P1.Output == O2
+ {
+ Take2(accumulated, next)
+ .map { tuple, next in
+ (repeat each tuple, next)
+ }
}
public struct SkipFirst: Parser
@@ -268,152 +206,6 @@ public enum ParserBuilder {
} catch { throw ParsingError.wrap(error, at: input) }
}
}
-
- public struct Take3: Parser
- where P0.Input == P1.Input, P0.Output == (O0, O1) {
- @usableFromInline let p0: P0, p1: P1
-
- @usableFromInline init(_ p0: P0, _ p1: P1) {
- self.p0 = p0
- self.p1 = p1
- }
-
- @inlinable public func parse(_ input: inout P0.Input) rethrows -> (O0, O1, P1.Output) {
- do {
- let (o0, o1) = try self.p0.parse(&input)
- return try (o0, o1, self.p1.parse(&input))
- } catch { throw ParsingError.wrap(error, at: input) }
- }
- }
-
- public struct Take4: Parser
- where P0.Input == P1.Input, P0.Output == (O0, O1, O2) {
- @usableFromInline let p0: P0, p1: P1
-
- @usableFromInline init(_ p0: P0, _ p1: P1) {
- self.p0 = p0
- self.p1 = p1
- }
-
- @inlinable public func parse(_ input: inout P0.Input) rethrows -> (O0, O1, O2, P1.Output) {
- do {
- let (o0, o1, o2) = try self.p0.parse(&input)
- return try (o0, o1, o2, self.p1.parse(&input))
- } catch { throw ParsingError.wrap(error, at: input) }
- }
- }
-
- public struct Take5: Parser
- where P0.Input == P1.Input, P0.Output == (O0, O1, O2, O3) {
- @usableFromInline let p0: P0, p1: P1
-
- @usableFromInline init(_ p0: P0, _ p1: P1) {
- self.p0 = p0
- self.p1 = p1
- }
-
- @inlinable public func parse(_ input: inout P0.Input) rethrows -> (O0, O1, O2, O3, P1.Output) {
- do {
- let (o0, o1, o2, o3) = try self.p0.parse(&input)
- return try (o0, o1, o2, o3, self.p1.parse(&input))
- } catch { throw ParsingError.wrap(error, at: input) }
- }
- }
-
- public struct Take6: Parser
- where P0.Input == P1.Input, P0.Output == (O0, O1, O2, O3, O4) {
- @usableFromInline let p0: P0, p1: P1
-
- @usableFromInline init(_ p0: P0, _ p1: P1) {
- self.p0 = p0
- self.p1 = p1
- }
-
- @inlinable public func parse(_ input: inout P0.Input) rethrows -> (
- O0, O1, O2, O3, O4, P1.Output
- ) {
- do {
- let (o0, o1, o2, o3, o4) = try self.p0.parse(&input)
- return try (o0, o1, o2, o3, o4, self.p1.parse(&input))
- } catch { throw ParsingError.wrap(error, at: input) }
- }
- }
-
- public struct Take7: Parser
- where P0.Input == P1.Input, P0.Output == (O0, O1, O2, O3, O4, O5) {
- @usableFromInline let p0: P0, p1: P1
-
- @usableFromInline init(_ p0: P0, _ p1: P1) {
- self.p0 = p0
- self.p1 = p1
- }
-
- @inlinable public func parse(_ input: inout P0.Input) rethrows -> (
- O0, O1, O2, O3, O4, O5, P1.Output
- ) {
- do {
- let (o0, o1, o2, o3, o4, o5) = try self.p0.parse(&input)
- return try (o0, o1, o2, o3, o4, o5, self.p1.parse(&input))
- } catch { throw ParsingError.wrap(error, at: input) }
- }
- }
-
- public struct Take8: Parser
- where P0.Input == P1.Input, P0.Output == (O0, O1, O2, O3, O4, O5, O6) {
- @usableFromInline let p0: P0, p1: P1
-
- @usableFromInline init(_ p0: P0, _ p1: P1) {
- self.p0 = p0
- self.p1 = p1
- }
-
- @inlinable public func parse(_ input: inout P0.Input) rethrows -> (
- O0, O1, O2, O3, O4, O5, O6, P1.Output
- ) {
- do {
- let (o0, o1, o2, o3, o4, o5, o6) = try self.p0.parse(&input)
- return try (o0, o1, o2, o3, o4, o5, o6, self.p1.parse(&input))
- } catch { throw ParsingError.wrap(error, at: input) }
- }
- }
-
- public struct Take9: Parser
- where P0.Input == P1.Input, P0.Output == (O0, O1, O2, O3, O4, O5, O6, O7) {
- @usableFromInline let p0: P0, p1: P1
-
- @usableFromInline init(_ p0: P0, _ p1: P1) {
- self.p0 = p0
- self.p1 = p1
- }
-
- @inlinable public func parse(_ input: inout P0.Input) rethrows -> (
- O0, O1, O2, O3, O4, O5, O6, O7, P1.Output
- ) {
- do {
- let (o0, o1, o2, o3, o4, o5, o6, o7) = try self.p0.parse(&input)
- return try (o0, o1, o2, o3, o4, o5, o6, o7, self.p1.parse(&input))
- } catch { throw ParsingError.wrap(error, at: input) }
- }
- }
-
- public struct Take10: Parser
- where P0.Input == P1.Input, P0.Output == (O0, O1, O2, O3, O4, O5, O6, O7, O8) {
- @usableFromInline let p0: P0, p1: P1
-
- @usableFromInline init(_ p0: P0, _ p1: P1) {
- self.p0 = p0
- self.p1 = p1
- }
-
- @inlinable public func parse(_ input: inout P0.Input) rethrows -> (
- O0, O1, O2, O3, O4, O5, O6, O7, O8, P1.Output
- ) {
- do {
- let (o0, o1, o2, o3, o4, o5, o6, o7, o8) = try self.p0.parse(&input)
- return try (o0, o1, o2, o3, o4, o5, o6, o7, o8, self.p1.parse(&input))
- } catch { throw ParsingError.wrap(error, at: input) }
- }
- }
}
extension ParserBuilder.SkipFirst: ParserPrinter where P0: ParserPrinter, P1: ParserPrinter {
@@ -440,93 +232,6 @@ extension ParserBuilder.Take2: ParserPrinter where P0: ParserPrinter, P1: Parser
}
}
-extension ParserBuilder.Take3: ParserPrinter where P0: ParserPrinter, P1: ParserPrinter {
- @inlinable
- public func print(_ output: (O0, O1, P1.Output), into input: inout P0.Input) rethrows {
- try self.p1.print(output.2, into: &input)
- try self.p0.print((output.0, output.1), into: &input)
- }
-}
-
-extension ParserBuilder.Take4: ParserPrinter where P0: ParserPrinter, P1: ParserPrinter {
- @inlinable
- public func print(_ output: (O0, O1, O2, P1.Output), into input: inout P0.Input) rethrows {
- try self.p1.print(output.3, into: &input)
- try self.p0.print((output.0, output.1, output.2), into: &input)
- }
-}
-
-extension ParserBuilder.Take5: ParserPrinter where P0: ParserPrinter, P1: ParserPrinter {
- @inlinable
- public func print(_ output: (O0, O1, O2, O3, P1.Output), into input: inout P0.Input) rethrows {
- try self.p1.print(output.4, into: &input)
- try self.p0.print((output.0, output.1, output.2, output.3), into: &input)
- }
-}
-
-extension ParserBuilder.Take6: ParserPrinter where P0: ParserPrinter, P1: ParserPrinter {
- @inlinable
- public func print(
- _ output: (O0, O1, O2, O3, O4, P1.Output),
- into input: inout P0.Input
- ) rethrows {
- try self.p1.print(output.5, into: &input)
- try self.p0.print((output.0, output.1, output.2, output.3, output.4), into: &input)
- }
-}
-
-extension ParserBuilder.Take7: ParserPrinter where P0: ParserPrinter, P1: ParserPrinter {
- @inlinable
- public func print(
- _ output: (O0, O1, O2, O3, O4, O5, P1.Output),
- into input: inout P0.Input
- ) rethrows {
- try self.p1.print(output.6, into: &input)
- try self.p0.print((output.0, output.1, output.2, output.3, output.4, output.5), into: &input)
- }
-}
-
-extension ParserBuilder.Take8: ParserPrinter where P0: ParserPrinter, P1: ParserPrinter {
- @inlinable
- public func print(
- _ output: (O0, O1, O2, O3, O4, O5, O6, P1.Output),
- into input: inout P0.Input
- ) rethrows {
- try self.p1.print(output.7, into: &input)
- try self.p0.print(
- (output.0, output.1, output.2, output.3, output.4, output.5, output.6),
- into: &input
- )
- }
-}
-
-extension ParserBuilder.Take9: ParserPrinter where P0: ParserPrinter, P1: ParserPrinter {
- @inlinable
- public func print(
- _ output: (O0, O1, O2, O3, O4, O5, O6, O7, P1.Output),
- into input: inout P0.Input
- ) rethrows {
- try self.p1.print(output.8, into: &input)
- try self.p0.print(
- (output.0, output.1, output.2, output.3, output.4, output.5, output.6, output.7),
- into: &input
- )
- }
-}
-
-extension ParserBuilder.Take10: ParserPrinter where P0: ParserPrinter, P1: ParserPrinter {
- @inlinable
- public func print(
- _ output: (O0, O1, O2, O3, O4, O5, O6, O7, O8, P1.Output),
- into input: inout P0.Input
- ) rethrows {
- try self.p1.print(output.9, into: &input)
- try self.p0.print(
- (output.0, output.1, output.2, output.3, output.4, output.5, output.6, output.7, output.8),
- into: &input
- )
- }
-}
extension ParserBuilder where Input == Substring {
@_disfavoredOverload
@@ -546,3 +251,33 @@ extension ParserBuilder where Input == Substring.UTF8View {
expression
}
}
+
+extension ParserBuilder.Take2 {
+ public struct Map: Parser where P0.Input == P1.Input {
+ let upstream: ParserBuilder.Take2
+ let transform: (P0.Output, P1.Output) -> NewOutput
+
+ public func parse(_ input: inout P0.Input) throws -> NewOutput {
+ let (first, second) = try upstream.parse(&input)
+ return transform(first, second)
+ }
+ }
+
+ public func map(_ transform: @escaping (P0.Output, P1.Output) -> NewOutput) -> Map {
+ Map(upstream: self, transform: transform)
+ }
+}
+
+extension ParserBuilder.Take2.Map: ParserPrinter
+where P0: ParserPrinter, P1: ParserPrinter {
+ public func print(_ output: NewOutput, into input: inout P0.Input) throws {
+ guard let tuple = output as? (P0.Output, P1.Output) else {
+ throw ParsingError.failed(
+ summary: "Could not convert output to required tuple type",
+ from: output,
+ to: input
+ )
+ }
+ try upstream.print(tuple, into: &input)
+ }
+}
diff --git a/Tests/ParsingTests/VariadicTests.swift b/Tests/ParsingTests/VariadicTests.swift
new file mode 100644
index 0000000000..0594037a22
--- /dev/null
+++ b/Tests/ParsingTests/VariadicTests.swift
@@ -0,0 +1,49 @@
+import Parsing
+import XCTest
+
+final class Over11Tests: XCTestCase {
+ func testOver11() throws {
+ struct ParserTest: Parser {
+ var body: some Parser {
+ Digits()
+ "."
+ Digits()
+ "."
+ Digits()
+ "."
+ Digits()
+ "."
+ Digits()
+ "."
+ Digits()
+ "."
+ Digits()
+ "."
+ Digits()
+ "."
+ Digits()
+ "."
+ Digits()
+ "."
+ Digits()
+ "."
+ Digits()
+ }
+ }
+
+ var input = "1.2.3.4.5.6.7.8.9.10.11.12"[...]
+ let output: (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int) = try ParserTest().parse(&input)
+ XCTAssertEqual(output.0, 1)
+ XCTAssertEqual(output.1, 2)
+ XCTAssertEqual(output.2, 3)
+ XCTAssertEqual(output.3, 4)
+ XCTAssertEqual(output.4, 5)
+ XCTAssertEqual(output.5, 6)
+ XCTAssertEqual(output.6, 7)
+ XCTAssertEqual(output.7, 8)
+ XCTAssertEqual(output.8, 9)
+ XCTAssertEqual(output.9, 10)
+ XCTAssertEqual(output.10, 11)
+ XCTAssertEqual(output.11, 12)
+ }
+}