From c6e2241daa46e5c6e5027a93b161bca6ba692bcc Mon Sep 17 00:00:00 2001 From: Stephen Celis Date: Fri, 31 Mar 2023 08:47:25 -0700 Subject: [PATCH] Swift 5.8 Support (#289) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Swift 5.8 Support Co-authored-by: Jaap Wijnen * wip * wip * wip * wip * wip * omit some benchmarks from swift 5.7 * wip * FromSubstring ParseBuilder needs Substring as Input (#292) * Downstream ParseBuilder should use Downstream.Input as Input (#291) * Downstream ParseBuilder should use Downstream.Input as Input The ParseBuilder is for Downstream so it should use it’s input. Or Upstream.Output as pipe runs the downstream parser on the output of the upstream parser. Which is why Upstream.Output == Downstream.Input. With the 5.8 changes pipe uses the wrong input here. This only causes issues, if Upstream and Downstream have a different Input type. * Pipe - Use Upstream.Output instead of Downstream.Input * wip * wip * wip * wip * wip * fix * wip --------- Co-authored-by: Jaap Wijnen Co-authored-by: Brandon Williams Co-authored-by: Kai Oelfke --- .github/workflows/ci.yml | 21 +- Makefile | 2 +- Package.swift | 18 +- README.md | 99 +- Sources/Parsing/Builders/OneOfBuilder.swift | 72 +- Sources/Parsing/Builders/ParserBuilder.swift | 86 +- Sources/Parsing/Builders/Variadics.swift | 10503 ---------------- Sources/Parsing/Conversion.swift | 59 +- .../Articles/ErrorMessages.md | 10 +- .../Articles/GettingStarted.md | 16 +- Sources/Parsing/Documentation.docc/Parsing.md | 5 +- Sources/Parsing/Internal/Deprecations.swift | 188 +- Sources/Parsing/Parser.swift | 116 +- Sources/Parsing/ParserPrinter.swift | 38 +- Sources/Parsing/ParserPrinters/Always.swift | 16 +- .../Parsing/ParserPrinters/Backtracking.swift | 4 +- Sources/Parsing/ParserPrinters/Bool.swift | 34 - Sources/Parsing/ParserPrinters/Consumed.swift | 7 +- Sources/Parsing/ParserPrinters/End.swift | 12 - Sources/Parsing/ParserPrinters/First.swift | 12 - Sources/Parsing/ParserPrinters/Float.swift | 36 - Sources/Parsing/ParserPrinters/From.swift | 8 +- Sources/Parsing/ParserPrinters/Int.swift | 46 - Sources/Parsing/ParserPrinters/Lazy.swift | 36 +- Sources/Parsing/ParserPrinters/Many.swift | 103 +- Sources/Parsing/ParserPrinters/Not.swift | 4 +- Sources/Parsing/ParserPrinters/OneOf.swift | 9 +- .../Parsing/ParserPrinters/Optionally.swift | 4 +- Sources/Parsing/ParserPrinters/Parse.swift | 30 +- .../ParserPrinters/ParseableFormatStyle.swift | 2 +- Sources/Parsing/ParserPrinters/Peek.swift | 4 +- Sources/Parsing/ParserPrinters/Pipe.swift | 7 +- Sources/Parsing/ParserPrinters/Prefix.swift | 28 - Sources/Parsing/ParserPrinters/Rest.swift | 12 - Sources/Parsing/ParserPrinters/Skip.swift | 4 +- Sources/Parsing/ParserPrinters/UUID.swift | 32 - .../Parsing/ParserPrinters/Whitespace.swift | 30 - Sources/Parsing/Parsers/FlatMap.swift | 6 +- Sources/Parsing/Parsers/Stream.swift | 5 +- Sources/Parsing/PrependableCollection.swift | 174 +- .../swift-parsing-benchmark/Arithmetic.swift | 37 +- .../swift-parsing-benchmark/BinaryData.swift | 337 +- Sources/swift-parsing-benchmark/CSV.swift | 56 +- Sources/swift-parsing-benchmark/Color.swift | 18 +- Sources/swift-parsing-benchmark/Date.swift | 142 +- Sources/swift-parsing-benchmark/HTTP.swift | 207 +- Sources/swift-parsing-benchmark/JSON.swift | 288 +- .../swift-parsing-benchmark/Numerics.swift | 36 +- Sources/swift-parsing-benchmark/Race.swift | 344 +- .../ReadmeExample.swift | 206 +- .../StringAbstractions.swift | 17 +- .../swift-parsing-benchmark/XCTestLogs.swift | 120 +- .../VariadicsGenerator.swift | 304 - Sources/variadics-generator/main.swift | 1 - Tests/ParsingTests/BacktrackTests.swift | 21 +- Tests/ParsingTests/BoolTests.swift | 4 +- .../CaseIterableRawRepresentableTests.swift | 59 +- Tests/ParsingTests/CaseIterableTests.swift | 22 +- Tests/ParsingTests/ConditionalTests.swift | 22 +- Tests/ParsingTests/ConsumedTests.swift | 8 +- Tests/ParsingTests/DigitsTests.swift | 16 +- Tests/ParsingTests/FromSubstringTests.swift | 32 +- Tests/ParsingTests/LazyTests.swift | 2 +- Tests/ParsingTests/ManyTests.swift | 197 +- Tests/ParsingTests/OneOfTests.swift | 353 +- Tests/ParsingTests/OptionallyTests.swift | 22 +- Tests/ParsingTests/ParseableFormatTests.swift | 2 +- Tests/ParsingTests/ParserBuilderTests.swift | 9 +- Tests/ParsingTests/ParsingErrorTests.swift | 5 +- Tests/ParsingTests/PeekTests.swift | 8 +- Tests/ParsingTests/PipeTests.swift | 14 + Tests/ParsingTests/PrefixTests.swift | 20 +- Tests/ParsingTests/RegressionTests.swift | 14 + Tests/ParsingTests/ReplaceErrorTests.swift | 2 +- Tests/ParsingTests/RestTests.swift | 4 +- Tests/ParsingTests/SkipTests.swift | 6 +- Tests/ParsingTests/UTF8Tests.swift | 2 +- 77 files changed, 2089 insertions(+), 12766 deletions(-) delete mode 100644 Sources/Parsing/Builders/Variadics.swift delete mode 100644 Sources/variadics-generator/VariadicsGenerator.swift delete mode 100644 Sources/variadics-generator/main.swift create mode 100644 Tests/ParsingTests/RegressionTests.swift diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d86995350b..2d2d1f2be5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,16 +11,16 @@ on: jobs: macos_tests: - runs-on: macos-11 + runs-on: macos-12 strategy: matrix: xcode: - - "13.2.1" # Swift 5.5 + - "14.2" # Swift 5.7.2 command: - test - - benchmarks + # - benchmarks steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Select Xcode ${{ matrix.xcode }} run: sudo xcode-select -s /Applications/Xcode_${{ matrix.xcode }}.app - name: System @@ -31,22 +31,13 @@ jobs: ubuntu_tests: strategy: matrix: - os: [ubuntu-18.04, ubuntu-20.04] + os: [ubuntu-20.04] runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Build run: swift build - name: Run tests run: swift test - - windows_tests: - runs-on: windows-2019 - - steps: - - uses: actions/checkout@v2 - - uses: MaxDesiatov/swift-windows-action@v1 - with: - swift-version: "5.5.1" diff --git a/Makefile b/Makefile index 2fe6249454..3530a1f596 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ PLATFORM_IOS = iOS Simulator,name=iPhone 11 Pro PLATFORM_MACOS = macOS -PLATFORM_TVOS = tvOS Simulator,name=Apple TV 4K (at 1080p) +PLATFORM_TVOS = tvOS Simulator,name=Apple TV default: test diff --git a/Package.swift b/Package.swift index acd163bd56..0ec8c0b25c 100644 --- a/Package.swift +++ b/Package.swift @@ -1,4 +1,4 @@ -// swift-tools-version:5.5 +// swift-tools-version:5.7 import PackageDescription @@ -18,9 +18,10 @@ let package = Package( ], dependencies: [ .package(url: "https://github.com/apple/swift-argument-parser", from: "0.5.0"), + .package(url: "https://github.com/apple/swift-docc-plugin", from: "1.0.0"), .package(url: "https://github.com/pointfreeco/swift-case-paths", from: "0.8.0"), .package(url: "https://github.com/pointfreeco/xctest-dynamic-overlay", from: "0.2.1"), - .package(name: "Benchmark", url: "https://github.com/google/swift-benchmark", from: "0.1.1"), + .package(url: "https://github.com/google/swift-benchmark", from: "0.1.1"), ], targets: [ .target( @@ -37,19 +38,8 @@ let package = Package( name: "swift-parsing-benchmark", dependencies: [ "Parsing", - .product(name: "Benchmark", package: "Benchmark"), + .product(name: "Benchmark", package: "swift-benchmark"), ] ), - .executableTarget( - name: "variadics-generator", - dependencies: [.product(name: "ArgumentParser", package: "swift-argument-parser")] - ), ] ) - -#if swift(>=5.6) - // Add the documentation compiler plugin if possible - package.dependencies.append( - .package(url: "https://github.com/apple/swift-docc-plugin", from: "1.0.0") - ) -#endif diff --git a/README.md b/README.md index 75988d55d8..171f0e9203 100644 --- a/README.md +++ b/README.md @@ -103,22 +103,26 @@ It would be more straightforward and efficient to instead describe how to consum We can start by describing what it means to parse a single row, first by parsing an integer off the front of the string, and then parsing a comma. We can do this by using the `Parse` type, which acts as an entry point into describing a list of parsers that you want to run one after the other to consume from an input: ```swift -let user = Parse { +let user = Parse(input: Substring.self) { Int.parser() "," } ``` +Note that this parsing library is quite general, allowing one to parse _any_ kind of input into +_any_ kind of output. For this reason we sometimes need to specify the exact input type the parser +can process, in this case substrings. + Already this can consume the beginning of the input: ```swift -try user.parse("1,") // 1 +try user.parse("1,") // 1 ``` Next we want to take everything up until the next comma for the user's name, and then consume the comma: ```swift -let user = Parse { +let user = Parse(input: Substring.self) { Int.parser() "," Prefix { $0 != "," } @@ -129,7 +133,7 @@ let user = Parse { And then we want to take the boolean at the end of the row for the user's admin status: ```swift -let user = Parse { +let user = Parse(input: Substring.self) { Int.parser() "," Prefix { $0 != "," } @@ -141,7 +145,7 @@ let user = Parse { Currently this will parse a tuple `(Int, Substring, Bool)` from the input, and we can `.map` on that to turn it into a `User`: ```swift -let user = Parse { +let user = Parse(input: Substring.self) { Int.parser() "," Prefix { $0 != "," } @@ -154,7 +158,7 @@ let user = Parse { To make the data we are parsing to more prominent, we can instead pass the transform closure as the first argument to `Parse`: ```swift -let user = Parse { +let user = Parse(input: Substring.self) { User(id: $0, name: String($1), isAdmin: $2) } with: { Int.parser() @@ -168,7 +172,7 @@ let user = Parse { Or we can pass the `User` initializer to `Parse` in a point-free style by transforming the `Prefix` parser's output from a `Substring` to ` String` first: ```swift -let user = Parse(User.init(id:name:isAdmin:)) { +let user = Parse(input: Substring.self, User.init(id:name:isAdmin:)) { Int.parser() "," Prefix { $0 != "," }.map(String.init) @@ -305,46 +309,47 @@ Apple M1 Pro (10 cores, 8 performance and 2 efficiency) name time std iterations ---------------------------------------------------------------------------------- -Arithmetic.Parser 8042.000 ns ± 5.91 % 174657 -BinaryData.Parser 42.000 ns ± 56.81 % 1000000 -Bool.Bool.init 41.000 ns ± 60.69 % 1000000 -Bool.Bool.parser 42.000 ns ± 57.28 % 1000000 -Bool.Scanner.scanBool 1041.000 ns ± 25.98 % 1000000 -Color.Parser 209.000 ns ± 13.68 % 1000000 -CSV.Parser 4047750.000 ns ± 1.18 % 349 -CSV.Ad hoc mutating methods 898604.000 ns ± 1.49 % 1596 -Date.Parser 6416.000 ns ± 2.56 % 219218 -Date.DateFormatter 25625.000 ns ± 2.19 % 54110 -Date.ISO8601DateFormatter 35125.000 ns ± 1.71 % 39758 -HTTP.HTTP 9709.000 ns ± 3.81 % 138868 -JSON.Parser 32292.000 ns ± 3.18 % 41890 -JSON.JSONSerialization 1833.000 ns ± 8.58 % 764057 -Numerics.Int.init 41.000 ns ± 84.54 % 1000000 -Numerics.Int.parser 42.000 ns ± 72.17 % 1000000 -Numerics.Scanner.scanInt 125.000 ns ± 20.26 % 1000000 -Numerics.Comma separated: Int.parser 8096459.000 ns ± 0.44 % 173 -Numerics.Comma separated: Scanner.scanInt 49178770.500 ns ± 0.24 % 28 -Numerics.Comma separated: String.split 14922583.500 ns ± 0.67 % 94 -Numerics.Double.init 42.000 ns ± 72.61 % 1000000 -Numerics.Double.parser 125.000 ns ± 58.57 % 1000000 -Numerics.Scanner.scanDouble 167.000 ns ± 18.84 % 1000000 -Numerics.Comma separated: Double.parser 11313395.500 ns ± 0.96 % 124 -Numerics.Comma separated: Scanner.scanDouble 50431521.000 ns ± 0.19 % 28 -Numerics.Comma separated: String.split 18744125.000 ns ± 0.46 % 75 -PrefixUpTo.Parser: Substring 249958.000 ns ± 0.88 % 5595 -PrefixUpTo.Parser: UTF8 13250.000 ns ± 2.96 % 105812 -PrefixUpTo.String.range(of:) 43084.000 ns ± 1.57 % 32439 -PrefixUpTo.Scanner.scanUpToString 47500.000 ns ± 1.27 % 29444 -Race.Parser 34417.000 ns ± 2.73 % 40502 -README Example.Parser: Substring 4000.000 ns ± 3.79 % 347868 -README Example.Parser: UTF8 1125.000 ns ± 7.92 % 1000000 -README Example.Ad hoc 3542.000 ns ± 4.13 % 394248 -README Example.Scanner 14292.000 ns ± 2.82 % 97922 -String Abstractions.Substring 934167.000 ns ± 0.60 % 1505 -String Abstractions.UTF8 158750.000 ns ± 1.36 % 8816 -UUID.UUID.init 209.000 ns ± 15.02 % 1000000 -UUID.UUID.parser 208.000 ns ± 24.17 % 1000000 -Xcode Logs.Parser 3768437.500 ns ± 0.56 % 372 +Arithmetic.Parser 6166.000 ns ± 10.73 % 228888 +BinaryData.Parser 208.000 ns ± 39.64 % 1000000 +Bool.Bool.init 41.000 ns ± 84.71 % 1000000 +Bool.Bool.parser 42.000 ns ± 87.86 % 1000000 +Bool.Scanner.scanBool 916.000 ns ± 30.55 % 1000000 +Color.Parser 208.000 ns ± 28.34 % 1000000 +CSV.Parser 3675250.000 ns ± 1.16 % 380 +CSV.Ad hoc mutating methods 651333.000 ns ± 1.00 % 2143 +Date.Parser 5833.000 ns ± 5.65 % 238924 +Date.DateFormatter 23542.000 ns ± 5.50 % 58766 +Date.ISO8601DateFormatter 29041.000 ns ± 3.31 % 48028 +HTTP.HTTP 10250.000 ns ± 6.24 % 135657 +JSON.Parser 38167.000 ns ± 3.26 % 36423 +JSON.JSONSerialization 1792.000 ns ± 54.14 % 753770 +Numerics.Int.init 0.000 ns ± inf % 1000000 +Numerics.Int.parser 83.000 ns ± 67.28 % 1000000 +Numerics.Scanner.scanInt 125.000 ns ± 38.65 % 1000000 +Numerics.Digits 83.000 ns ± 65.03 % 1000000 +Numerics.Comma separated: Int.parser 15364583.000 ns ± 0.63 % 91 +Numerics.Comma separated: Scanner.scanInt 50654458.500 ns ± 0.30 % 28 +Numerics.Comma separated: String.split 15452542.000 ns ± 1.30 % 90 +Numerics.Double.init 42.000 ns ± 152.57 % 1000000 +Numerics.Double.parser 166.000 ns ± 45.23 % 1000000 +Numerics.Scanner.scanDouble 167.000 ns ± 42.36 % 1000000 +Numerics.Comma separated: Double.parser 18539833.000 ns ± 0.57 % 75 +Numerics.Comma separated: Scanner.scanDouble 55239167.000 ns ± 0.46 % 25 +Numerics.Comma separated: String.split 17636000.000 ns ± 1.34 % 78 +PrefixUpTo.Parser: Substring 182041.000 ns ± 1.78 % 7643 +PrefixUpTo.Parser: UTF8 40417.000 ns ± 2.71 % 34379 +PrefixUpTo.String.range(of:) 49792.000 ns ± 2.70 % 27891 +PrefixUpTo.Scanner.scanUpToString 53959.000 ns ± 3.87 % 25745 +Race.Parser 59583.000 ns ± 2.78 % 23333 +README Example.Parser: Substring 2834.000 ns ± 12.87 % 488264 +README Example.Parser: UTF8 1291.000 ns ± 22.65 % 1000000 +README Example.Ad hoc 2459.000 ns ± 20.61 % 561930 +README Example.Scanner 12084.000 ns ± 5.53 % 115388 +String Abstractions.Substring 472083.500 ns ± 1.38 % 2962 +String Abstractions.UTF8 196041.000 ns ± 3.38 % 7059 +UUID.UUID.init 208.000 ns ± 43.60 % 1000000 +UUID.UUID.parser 167.000 ns ± 42.00 % 1000000 +Xcode Logs.Parser 4511625.500 ns ± 0.58 % 226 ``` ## Documentation diff --git a/Sources/Parsing/Builders/OneOfBuilder.swift b/Sources/Parsing/Builders/OneOfBuilder.swift index 150babbe39..e1f69d9c47 100644 --- a/Sources/Parsing/Builders/OneOfBuilder.swift +++ b/Sources/Parsing/Builders/OneOfBuilder.swift @@ -17,7 +17,7 @@ /// try currency.parse("$100") // (.usd, 100) /// ``` @resultBuilder -public enum OneOfBuilder { +public enum OneOfBuilder { /// Provides support for `for`-`in` loops in ``OneOfBuilder`` blocks. /// /// Useful for building up a parser from a dynamic source, like for a case-iterable enum: @@ -36,23 +36,23 @@ public enum OneOfBuilder { /// } /// ``` @inlinable - public static func buildArray

(_ parsers: [P]) -> Parsers.OneOfMany

{ + public static func buildArray

(_ parsers: [P]) -> Parsers.OneOfMany

+ where P.Input == Input, P.Output == Output { .init(parsers) } + @inlinable + static public func buildBlock() -> Fail { + Fail() + } + /// Provides support for specifying a parser in ``OneOfBuilder`` blocks. @inlinable - static public func buildBlock(_ parser: P) -> P { + static public func buildBlock(_ parser: P) -> P + where P.Input == Input, P.Output == Output { parser } - #if swift(<5.7) - @inlinable - static public func buildBlock(_ p0: P0, _ p1: P1) -> OneOf2 { - OneOf2(p0, p1) - } - #endif - /// Provides support for `if`-`else` statements in ``OneOfBuilder`` blocks, producing a /// conditional parser for the `if` branch. /// @@ -68,7 +68,13 @@ public enum OneOfBuilder { @inlinable public static func buildEither( first parser: TrueParser - ) -> Parsers.Conditional { + ) -> Parsers.Conditional + where + TrueParser.Input == Input, + TrueParser.Output == Output, + FalseParser.Input == Input, + FalseParser.Output == Output + { .first(parser) } @@ -87,10 +93,22 @@ public enum OneOfBuilder { @inlinable public static func buildEither( second parser: FalseParser - ) -> Parsers.Conditional { + ) -> Parsers.Conditional + where + TrueParser.Input == Input, + TrueParser.Output == Output, + FalseParser.Input == Input, + FalseParser.Output == Output + { .second(parser) } + @inlinable + public static func buildExpression(_ parser: P) -> P + where P.Input == Input, P.Output == Output { + parser + } + /// Provides support for `if` statements in ``OneOfBuilder`` blocks, producing an optional parser. /// /// ```swift @@ -106,24 +124,27 @@ public enum OneOfBuilder { /// } /// ``` @inlinable - public static func buildIf

(_ parser: P?) -> OptionalOneOf

{ + public static func buildIf

(_ parser: P?) -> OptionalOneOf

where P.Input == Input { .init(wrapped: parser) } /// Provides support for `if #available` statements in ``OneOfBuilder`` blocks, producing an /// optional parser. @inlinable - public static func buildLimitedAvailability

(_ parser: P?) -> OptionalOneOf

{ + public static func buildLimitedAvailability

(_ parser: P?) -> OptionalOneOf

+ where P.Input == Input, P.Output == Output { .init(wrapped: parser) } @inlinable - public static func buildPartialBlock(first: P0) -> P0 { + public static func buildPartialBlock(first: P) -> P + where P.Input == Input, P.Output == Output { first } @inlinable - public static func buildPartialBlock(accumulated: P0, next: P1) -> OneOf2 { + public static func buildPartialBlock(accumulated: P0, next: P1) -> OneOf2 + where P0.Input == Input, P0.Output == Output, P1.Input == Input, P1.Output == Output { .init(accumulated, next) } @@ -211,3 +232,22 @@ extension OneOfBuilder.OptionalOneOf: ParserPrinter where Wrapped: ParserPrinter try wrapped.print(output, into: &input) } } + +extension OneOfBuilder where Input == Substring { + @_disfavoredOverload + public static func buildExpression(_ parser: P) + -> From + where P.Input == Substring.UTF8View { + From(.utf8) { + parser + } + } +} + +extension OneOfBuilder where Input == Substring.UTF8View { + @_disfavoredOverload + public static func buildExpression(_ parser: P) -> P + where P.Input == Substring.UTF8View { + parser + } +} diff --git a/Sources/Parsing/Builders/ParserBuilder.swift b/Sources/Parsing/Builders/ParserBuilder.swift index 8ec25cfbf6..b97b5289de 100644 --- a/Sources/Parsing/Builders/ParserBuilder.swift +++ b/Sources/Parsing/Builders/ParserBuilder.swift @@ -13,9 +13,14 @@ /// .parse("123,456") // (123, 456) /// ``` @resultBuilder -public enum ParserBuilder { +public enum ParserBuilder { @inlinable - public static func buildBlock(_ parser: P) -> P { + public static func buildBlock() -> Always { + Always(()) + } + + @inlinable + public static func buildBlock(_ parser: P) -> P where P.Input == Input { parser } @@ -36,7 +41,8 @@ public enum ParserBuilder { @inlinable public static func buildEither( first parser: TrueParser - ) -> Parsers.Conditional { + ) -> Parsers.Conditional + where TrueParser.Input == Input, FalseParser.Input == Input { .first(parser) } @@ -57,14 +63,20 @@ public enum ParserBuilder { @inlinable public static func buildEither( second parser: FalseParser - ) -> Parsers.Conditional { + ) -> Parsers.Conditional + where TrueParser.Input == Input, FalseParser.Input == Input { .second(parser) } + @inlinable + public static func buildExpression(_ parser: P) -> P where P.Input == Input { + parser + } + /// Provides support for `if` statements in ``ParserBuilder`` blocks, producing an optional /// parser. @inlinable - public static func buildIf(_ parser: P?) -> P? { + public static func buildIf(_ parser: P?) -> P? where P.Input == Input { parser } @@ -82,43 +94,50 @@ public enum ParserBuilder { /// } /// ``` @inlinable - public static func buildIf

(_ parser: P?) -> Parsers.OptionalVoid

{ + public static func buildIf

(_ parser: P?) -> Parsers.OptionalVoid

+ where P.Input == Input { .init(wrapped: parser) } /// Provides support for `if #available` statements in ``ParserBuilder`` blocks, producing an /// optional parser. @inlinable - public static func buildLimitedAvailability(_ parser: P?) -> P? { + public static func buildLimitedAvailability(_ parser: P?) -> P? + where P.Input == Input { parser } /// Provides support for `if #available` statements in ``ParserBuilder`` blocks, producing a void /// parser for a given void parser. @inlinable - public static func buildLimitedAvailability

(_ parser: P?) -> Parsers.OptionalVoid

{ + public static func buildLimitedAvailability

(_ parser: P?) -> Parsers.OptionalVoid

+ where P.Input == Input { .init(wrapped: parser) } @inlinable - public static func buildPartialBlock(first: P) -> P { + public static func buildPartialBlock(first: P) -> P + where P.Input == Input { first } @_disfavoredOverload @inlinable - public static func buildPartialBlock(accumulated: P0, next: P1) -> SkipFirst { + public static func buildPartialBlock(accumulated: P0, next: P1) -> SkipFirst + where P0.Input == Input, P1.Input == Input { .init(accumulated, next) } @inlinable - public static func buildPartialBlock(accumulated: P0, next: P1) -> SkipSecond { + 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 { + public static func buildPartialBlock(accumulated: P0, next: P1) -> Take2 + where P0.Input == Input, P1.Input == Input { .init(accumulated, next) } @@ -126,7 +145,8 @@ public enum ParserBuilder { @inlinable public static func buildPartialBlock( accumulated: P0, next: P1 - ) -> Take3 { + ) -> Take3 + where P0.Input == Input, P1.Input == Input { .init(accumulated, next) } @@ -134,7 +154,8 @@ public enum ParserBuilder { @inlinable public static func buildPartialBlock( accumulated: P0, next: P1 - ) -> Take4 { + ) -> Take4 + where P0.Input == Input, P1.Input == Input { .init(accumulated, next) } @@ -142,7 +163,8 @@ public enum ParserBuilder { @inlinable public static func buildPartialBlock( accumulated: P0, next: P1 - ) -> Take5 { + ) -> Take5 + where P0.Input == Input, P1.Input == Input { .init(accumulated, next) } @@ -150,7 +172,8 @@ public enum ParserBuilder { @inlinable public static func buildPartialBlock( accumulated: P0, next: P1 - ) -> Take6 { + ) -> Take6 + where P0.Input == Input, P1.Input == Input { .init(accumulated, next) } @@ -158,7 +181,8 @@ public enum ParserBuilder { @inlinable public static func buildPartialBlock( accumulated: P0, next: P1 - ) -> Take7 { + ) -> Take7 + where P0.Input == Input, P1.Input == Input { .init(accumulated, next) } @@ -166,7 +190,8 @@ public enum ParserBuilder { @inlinable public static func buildPartialBlock( accumulated: P0, next: P1 - ) -> Take8 { + ) -> Take8 + where P0.Input == Input, P1.Input == Input { .init(accumulated, next) } @@ -174,7 +199,8 @@ public enum ParserBuilder { @inlinable public static func buildPartialBlock( accumulated: P0, next: P1 - ) -> Take9 { + ) -> Take9 + where P0.Input == Input, P1.Input == Input { .init(accumulated, next) } @@ -182,7 +208,8 @@ public enum ParserBuilder { @inlinable public static func buildPartialBlock( accumulated: P0, next: P1 - ) -> Take10 { + ) -> Take10 + where P0.Input == Input, P1.Input == Input { .init(accumulated, next) } @@ -500,3 +527,22 @@ extension ParserBuilder.Take10: ParserPrinter where P0: ParserPrinter, P1: Parse ) } } + +extension ParserBuilder where Input == Substring { + @_disfavoredOverload + public static func buildExpression(_ expression: P) + -> From + where P.Input == Substring.UTF8View { + From(.utf8) { + expression + } + } +} + +extension ParserBuilder where Input == Substring.UTF8View { + @_disfavoredOverload + public static func buildExpression(_ expression: P) -> P + where P.Input == Substring.UTF8View { + expression + } +} diff --git a/Sources/Parsing/Builders/Variadics.swift b/Sources/Parsing/Builders/Variadics.swift deleted file mode 100644 index b3e883b4fe..0000000000 --- a/Sources/Parsing/Builders/Variadics.swift +++ /dev/null @@ -1,10503 +0,0 @@ -// BEGIN AUTO-GENERATED CONTENT - -#if swift(<5.7) - - extension ParserBuilder { - public struct ZipOO: Parser - where - P0.Input == P1.Input - { - public let p0: P0, p1: P1 - - @inlinable public init(_ p0: P0, _ p1: P1) { - self.p0 = p0 - self.p1 = p1 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P0.Output, - P1.Output - ) { - do { - let o0 = try p0.parse(&input) - let o1 = try p1.parse(&input) - return (o0, o1) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipOO: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P0.Input == P1.Input - { - @inlinable public func print( - _ output: ( - P0.Output, - P1.Output - ), - into input: inout P0.Input - ) rethrows { - try p1.print(output.1, into: &input) - try p0.print(output.0, into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1 - ) -> ParserBuilder.ZipOO { - ParserBuilder.ZipOO(p0, p1) - } - } - - extension ParserBuilder { - public struct ZipOV: Parser - where - P0.Input == P1.Input, - P1.Output == Void - { - public let p0: P0, p1: P1 - - @inlinable public init(_ p0: P0, _ p1: P1) { - self.p0 = p0 - self.p1 = p1 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> P0.Output { - do { - let o0 = try p0.parse(&input) - try p1.parse(&input) - return o0 - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipOV: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P0.Input == P1.Input, - P1.Output == Void - { - @inlinable public func print( - _ output: P0.Output, - into input: inout P0.Input - ) rethrows { - try p1.print(into: &input) - try p0.print(output, into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1 - ) -> ParserBuilder.ZipOV { - ParserBuilder.ZipOV(p0, p1) - } - } - - extension ParserBuilder { - public struct ZipVO: Parser - where - P0.Input == P1.Input, - P0.Output == Void - { - public let p0: P0, p1: P1 - - @inlinable public init(_ p0: P0, _ p1: P1) { - self.p0 = p0 - self.p1 = p1 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> P1.Output { - do { - try p0.parse(&input) - let o1 = try p1.parse(&input) - return o1 - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipVO: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P0.Input == P1.Input, - P0.Output == Void - { - @inlinable public func print( - _ output: P1.Output, - into input: inout P0.Input - ) rethrows { - try p1.print(output, into: &input) - try p0.print(into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1 - ) -> ParserBuilder.ZipVO { - ParserBuilder.ZipVO(p0, p1) - } - } - - extension ParserBuilder { - public struct ZipVV: Parser - where - P0.Input == P1.Input, - P0.Output == Void, - P1.Output == Void - { - public let p0: P0, p1: P1 - - @inlinable public init(_ p0: P0, _ p1: P1) { - self.p0 = p0 - self.p1 = p1 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows { - do { - try p0.parse(&input) - try p1.parse(&input) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipVV: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P0.Input == P1.Input, - P0.Output == Void, - P1.Output == Void - { - @inlinable public func print( - _ output: Void, - into input: inout P0.Input - ) rethrows { - try p1.print(into: &input) - try p0.print(into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1 - ) -> ParserBuilder.ZipVV { - ParserBuilder.ZipVV(p0, p1) - } - } - - extension ParserBuilder { - public struct ZipOOO: Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input - { - public let p0: P0, p1: P1, p2: P2 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P0.Output, - P1.Output, - P2.Output - ) { - do { - let o0 = try p0.parse(&input) - let o1 = try p1.parse(&input) - let o2 = try p2.parse(&input) - return (o0, o1, o2) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipOOO: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input - { - @inlinable public func print( - _ output: ( - P0.Output, - P1.Output, - P2.Output - ), - into input: inout P0.Input - ) rethrows { - try p2.print(output.2, into: &input) - try p1.print(output.1, into: &input) - try p0.print(output.0, into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2 - ) -> ParserBuilder.ZipOOO { - ParserBuilder.ZipOOO(p0, p1, p2) - } - } - - extension ParserBuilder { - public struct ZipOOV: Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Output == Void - { - public let p0: P0, p1: P1, p2: P2 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P0.Output, - P1.Output - ) { - do { - let o0 = try p0.parse(&input) - let o1 = try p1.parse(&input) - try p2.parse(&input) - return (o0, o1) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipOOV: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Output == Void - { - @inlinable public func print( - _ output: ( - P0.Output, - P1.Output - ), - into input: inout P0.Input - ) rethrows { - try p2.print(into: &input) - try p1.print(output.1, into: &input) - try p0.print(output.0, into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2 - ) -> ParserBuilder.ZipOOV { - ParserBuilder.ZipOOV(p0, p1, p2) - } - } - - extension ParserBuilder { - public struct ZipOVO: Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P1.Output == Void - { - public let p0: P0, p1: P1, p2: P2 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P0.Output, - P2.Output - ) { - do { - let o0 = try p0.parse(&input) - try p1.parse(&input) - let o2 = try p2.parse(&input) - return (o0, o2) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipOVO: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P1.Output == Void - { - @inlinable public func print( - _ output: ( - P0.Output, - P2.Output - ), - into input: inout P0.Input - ) rethrows { - try p2.print(output.1, into: &input) - try p1.print(into: &input) - try p0.print(output.0, into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2 - ) -> ParserBuilder.ZipOVO { - ParserBuilder.ZipOVO(p0, p1, p2) - } - } - - extension ParserBuilder { - public struct ZipOVV: Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P1.Output == Void, - P2.Output == Void - { - public let p0: P0, p1: P1, p2: P2 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> P0.Output { - do { - let o0 = try p0.parse(&input) - try p1.parse(&input) - try p2.parse(&input) - return o0 - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipOVV: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P1.Output == Void, - P2.Output == Void - { - @inlinable public func print( - _ output: P0.Output, - into input: inout P0.Input - ) rethrows { - try p2.print(into: &input) - try p1.print(into: &input) - try p0.print(output, into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2 - ) -> ParserBuilder.ZipOVV { - ParserBuilder.ZipOVV(p0, p1, p2) - } - } - - extension ParserBuilder { - public struct ZipVOO: Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P0.Output == Void - { - public let p0: P0, p1: P1, p2: P2 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P1.Output, - P2.Output - ) { - do { - try p0.parse(&input) - let o1 = try p1.parse(&input) - let o2 = try p2.parse(&input) - return (o1, o2) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipVOO: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P0.Output == Void - { - @inlinable public func print( - _ output: ( - P1.Output, - P2.Output - ), - into input: inout P0.Input - ) rethrows { - try p2.print(output.1, into: &input) - try p1.print(output.0, into: &input) - try p0.print(into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2 - ) -> ParserBuilder.ZipVOO { - ParserBuilder.ZipVOO(p0, p1, p2) - } - } - - extension ParserBuilder { - public struct ZipVOV: Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P0.Output == Void, - P2.Output == Void - { - public let p0: P0, p1: P1, p2: P2 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> P1.Output { - do { - try p0.parse(&input) - let o1 = try p1.parse(&input) - try p2.parse(&input) - return o1 - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipVOV: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P0.Output == Void, - P2.Output == Void - { - @inlinable public func print( - _ output: P1.Output, - into input: inout P0.Input - ) rethrows { - try p2.print(into: &input) - try p1.print(output, into: &input) - try p0.print(into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2 - ) -> ParserBuilder.ZipVOV { - ParserBuilder.ZipVOV(p0, p1, p2) - } - } - - extension ParserBuilder { - public struct ZipVVO: Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P0.Output == Void, - P1.Output == Void - { - public let p0: P0, p1: P1, p2: P2 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> P2.Output { - do { - try p0.parse(&input) - try p1.parse(&input) - let o2 = try p2.parse(&input) - return o2 - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipVVO: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P0.Output == Void, - P1.Output == Void - { - @inlinable public func print( - _ output: P2.Output, - into input: inout P0.Input - ) rethrows { - try p2.print(output, into: &input) - try p1.print(into: &input) - try p0.print(into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2 - ) -> ParserBuilder.ZipVVO { - ParserBuilder.ZipVVO(p0, p1, p2) - } - } - - extension ParserBuilder { - public struct ZipVVV: Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P0.Output == Void, - P1.Output == Void, - P2.Output == Void - { - public let p0: P0, p1: P1, p2: P2 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows { - do { - try p0.parse(&input) - try p1.parse(&input) - try p2.parse(&input) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipVVV: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P0.Output == Void, - P1.Output == Void, - P2.Output == Void - { - @inlinable public func print( - _ output: Void, - into input: inout P0.Input - ) rethrows { - try p2.print(into: &input) - try p1.print(into: &input) - try p0.print(into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2 - ) -> ParserBuilder.ZipVVV { - ParserBuilder.ZipVVV(p0, p1, p2) - } - } - - extension ParserBuilder { - public struct ZipOOOO: Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input - { - public let p0: P0, p1: P1, p2: P2, p3: P3 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P0.Output, - P1.Output, - P2.Output, - P3.Output - ) { - do { - let o0 = try p0.parse(&input) - let o1 = try p1.parse(&input) - let o2 = try p2.parse(&input) - let o3 = try p3.parse(&input) - return (o0, o1, o2, o3) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipOOOO: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input - { - @inlinable public func print( - _ output: ( - P0.Output, - P1.Output, - P2.Output, - P3.Output - ), - into input: inout P0.Input - ) rethrows { - try p3.print(output.3, into: &input) - try p2.print(output.2, into: &input) - try p1.print(output.1, into: &input) - try p0.print(output.0, into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3 - ) -> ParserBuilder.ZipOOOO { - ParserBuilder.ZipOOOO(p0, p1, p2, p3) - } - } - - extension ParserBuilder { - public struct ZipOOOV: Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P0.Output, - P1.Output, - P2.Output - ) { - do { - let o0 = try p0.parse(&input) - let o1 = try p1.parse(&input) - let o2 = try p2.parse(&input) - try p3.parse(&input) - return (o0, o1, o2) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipOOOV: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Output == Void - { - @inlinable public func print( - _ output: ( - P0.Output, - P1.Output, - P2.Output - ), - into input: inout P0.Input - ) rethrows { - try p3.print(into: &input) - try p2.print(output.2, into: &input) - try p1.print(output.1, into: &input) - try p0.print(output.0, into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3 - ) -> ParserBuilder.ZipOOOV { - ParserBuilder.ZipOOOV(p0, p1, p2, p3) - } - } - - extension ParserBuilder { - public struct ZipOOVO: Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P2.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P0.Output, - P1.Output, - P3.Output - ) { - do { - let o0 = try p0.parse(&input) - let o1 = try p1.parse(&input) - try p2.parse(&input) - let o3 = try p3.parse(&input) - return (o0, o1, o3) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipOOVO: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P2.Output == Void - { - @inlinable public func print( - _ output: ( - P0.Output, - P1.Output, - P3.Output - ), - into input: inout P0.Input - ) rethrows { - try p3.print(output.2, into: &input) - try p2.print(into: &input) - try p1.print(output.1, into: &input) - try p0.print(output.0, into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3 - ) -> ParserBuilder.ZipOOVO { - ParserBuilder.ZipOOVO(p0, p1, p2, p3) - } - } - - extension ParserBuilder { - public struct ZipOOVV: Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P2.Output == Void, - P3.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P0.Output, - P1.Output - ) { - do { - let o0 = try p0.parse(&input) - let o1 = try p1.parse(&input) - try p2.parse(&input) - try p3.parse(&input) - return (o0, o1) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipOOVV: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P2.Output == Void, - P3.Output == Void - { - @inlinable public func print( - _ output: ( - P0.Output, - P1.Output - ), - into input: inout P0.Input - ) rethrows { - try p3.print(into: &input) - try p2.print(into: &input) - try p1.print(output.1, into: &input) - try p0.print(output.0, into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3 - ) -> ParserBuilder.ZipOOVV { - ParserBuilder.ZipOOVV(p0, p1, p2, p3) - } - } - - extension ParserBuilder { - public struct ZipOVOO: Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P1.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P0.Output, - P2.Output, - P3.Output - ) { - do { - let o0 = try p0.parse(&input) - try p1.parse(&input) - let o2 = try p2.parse(&input) - let o3 = try p3.parse(&input) - return (o0, o2, o3) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipOVOO: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P1.Output == Void - { - @inlinable public func print( - _ output: ( - P0.Output, - P2.Output, - P3.Output - ), - into input: inout P0.Input - ) rethrows { - try p3.print(output.2, into: &input) - try p2.print(output.1, into: &input) - try p1.print(into: &input) - try p0.print(output.0, into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3 - ) -> ParserBuilder.ZipOVOO { - ParserBuilder.ZipOVOO(p0, p1, p2, p3) - } - } - - extension ParserBuilder { - public struct ZipOVOV: Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P1.Output == Void, - P3.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P0.Output, - P2.Output - ) { - do { - let o0 = try p0.parse(&input) - try p1.parse(&input) - let o2 = try p2.parse(&input) - try p3.parse(&input) - return (o0, o2) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipOVOV: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P1.Output == Void, - P3.Output == Void - { - @inlinable public func print( - _ output: ( - P0.Output, - P2.Output - ), - into input: inout P0.Input - ) rethrows { - try p3.print(into: &input) - try p2.print(output.1, into: &input) - try p1.print(into: &input) - try p0.print(output.0, into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3 - ) -> ParserBuilder.ZipOVOV { - ParserBuilder.ZipOVOV(p0, p1, p2, p3) - } - } - - extension ParserBuilder { - public struct ZipOVVO: Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P1.Output == Void, - P2.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P0.Output, - P3.Output - ) { - do { - let o0 = try p0.parse(&input) - try p1.parse(&input) - try p2.parse(&input) - let o3 = try p3.parse(&input) - return (o0, o3) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipOVVO: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P1.Output == Void, - P2.Output == Void - { - @inlinable public func print( - _ output: ( - P0.Output, - P3.Output - ), - into input: inout P0.Input - ) rethrows { - try p3.print(output.1, into: &input) - try p2.print(into: &input) - try p1.print(into: &input) - try p0.print(output.0, into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3 - ) -> ParserBuilder.ZipOVVO { - ParserBuilder.ZipOVVO(p0, p1, p2, p3) - } - } - - extension ParserBuilder { - public struct ZipOVVV: Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P1.Output == Void, - P2.Output == Void, - P3.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> P0.Output { - do { - let o0 = try p0.parse(&input) - try p1.parse(&input) - try p2.parse(&input) - try p3.parse(&input) - return o0 - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipOVVV: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P1.Output == Void, - P2.Output == Void, - P3.Output == Void - { - @inlinable public func print( - _ output: P0.Output, - into input: inout P0.Input - ) rethrows { - try p3.print(into: &input) - try p2.print(into: &input) - try p1.print(into: &input) - try p0.print(output, into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3 - ) -> ParserBuilder.ZipOVVV { - ParserBuilder.ZipOVVV(p0, p1, p2, p3) - } - } - - extension ParserBuilder { - public struct ZipVOOO: Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P0.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P1.Output, - P2.Output, - P3.Output - ) { - do { - try p0.parse(&input) - let o1 = try p1.parse(&input) - let o2 = try p2.parse(&input) - let o3 = try p3.parse(&input) - return (o1, o2, o3) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipVOOO: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P0.Output == Void - { - @inlinable public func print( - _ output: ( - P1.Output, - P2.Output, - P3.Output - ), - into input: inout P0.Input - ) rethrows { - try p3.print(output.2, into: &input) - try p2.print(output.1, into: &input) - try p1.print(output.0, into: &input) - try p0.print(into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3 - ) -> ParserBuilder.ZipVOOO { - ParserBuilder.ZipVOOO(p0, p1, p2, p3) - } - } - - extension ParserBuilder { - public struct ZipVOOV: Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P0.Output == Void, - P3.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P1.Output, - P2.Output - ) { - do { - try p0.parse(&input) - let o1 = try p1.parse(&input) - let o2 = try p2.parse(&input) - try p3.parse(&input) - return (o1, o2) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipVOOV: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P0.Output == Void, - P3.Output == Void - { - @inlinable public func print( - _ output: ( - P1.Output, - P2.Output - ), - into input: inout P0.Input - ) rethrows { - try p3.print(into: &input) - try p2.print(output.1, into: &input) - try p1.print(output.0, into: &input) - try p0.print(into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3 - ) -> ParserBuilder.ZipVOOV { - ParserBuilder.ZipVOOV(p0, p1, p2, p3) - } - } - - extension ParserBuilder { - public struct ZipVOVO: Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P0.Output == Void, - P2.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P1.Output, - P3.Output - ) { - do { - try p0.parse(&input) - let o1 = try p1.parse(&input) - try p2.parse(&input) - let o3 = try p3.parse(&input) - return (o1, o3) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipVOVO: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P0.Output == Void, - P2.Output == Void - { - @inlinable public func print( - _ output: ( - P1.Output, - P3.Output - ), - into input: inout P0.Input - ) rethrows { - try p3.print(output.1, into: &input) - try p2.print(into: &input) - try p1.print(output.0, into: &input) - try p0.print(into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3 - ) -> ParserBuilder.ZipVOVO { - ParserBuilder.ZipVOVO(p0, p1, p2, p3) - } - } - - extension ParserBuilder { - public struct ZipVOVV: Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P0.Output == Void, - P2.Output == Void, - P3.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> P1.Output { - do { - try p0.parse(&input) - let o1 = try p1.parse(&input) - try p2.parse(&input) - try p3.parse(&input) - return o1 - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipVOVV: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P0.Output == Void, - P2.Output == Void, - P3.Output == Void - { - @inlinable public func print( - _ output: P1.Output, - into input: inout P0.Input - ) rethrows { - try p3.print(into: &input) - try p2.print(into: &input) - try p1.print(output, into: &input) - try p0.print(into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3 - ) -> ParserBuilder.ZipVOVV { - ParserBuilder.ZipVOVV(p0, p1, p2, p3) - } - } - - extension ParserBuilder { - public struct ZipVVOO: Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P0.Output == Void, - P1.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P2.Output, - P3.Output - ) { - do { - try p0.parse(&input) - try p1.parse(&input) - let o2 = try p2.parse(&input) - let o3 = try p3.parse(&input) - return (o2, o3) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipVVOO: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P0.Output == Void, - P1.Output == Void - { - @inlinable public func print( - _ output: ( - P2.Output, - P3.Output - ), - into input: inout P0.Input - ) rethrows { - try p3.print(output.1, into: &input) - try p2.print(output.0, into: &input) - try p1.print(into: &input) - try p0.print(into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3 - ) -> ParserBuilder.ZipVVOO { - ParserBuilder.ZipVVOO(p0, p1, p2, p3) - } - } - - extension ParserBuilder { - public struct ZipVVOV: Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P0.Output == Void, - P1.Output == Void, - P3.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> P2.Output { - do { - try p0.parse(&input) - try p1.parse(&input) - let o2 = try p2.parse(&input) - try p3.parse(&input) - return o2 - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipVVOV: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P0.Output == Void, - P1.Output == Void, - P3.Output == Void - { - @inlinable public func print( - _ output: P2.Output, - into input: inout P0.Input - ) rethrows { - try p3.print(into: &input) - try p2.print(output, into: &input) - try p1.print(into: &input) - try p0.print(into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3 - ) -> ParserBuilder.ZipVVOV { - ParserBuilder.ZipVVOV(p0, p1, p2, p3) - } - } - - extension ParserBuilder { - public struct ZipVVVO: Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P0.Output == Void, - P1.Output == Void, - P2.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> P3.Output { - do { - try p0.parse(&input) - try p1.parse(&input) - try p2.parse(&input) - let o3 = try p3.parse(&input) - return o3 - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipVVVO: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P0.Output == Void, - P1.Output == Void, - P2.Output == Void - { - @inlinable public func print( - _ output: P3.Output, - into input: inout P0.Input - ) rethrows { - try p3.print(output, into: &input) - try p2.print(into: &input) - try p1.print(into: &input) - try p0.print(into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3 - ) -> ParserBuilder.ZipVVVO { - ParserBuilder.ZipVVVO(p0, p1, p2, p3) - } - } - - extension ParserBuilder { - public struct ZipVVVV: Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P0.Output == Void, - P1.Output == Void, - P2.Output == Void, - P3.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows { - do { - try p0.parse(&input) - try p1.parse(&input) - try p2.parse(&input) - try p3.parse(&input) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipVVVV: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P0.Output == Void, - P1.Output == Void, - P2.Output == Void, - P3.Output == Void - { - @inlinable public func print( - _ output: Void, - into input: inout P0.Input - ) rethrows { - try p3.print(into: &input) - try p2.print(into: &input) - try p1.print(into: &input) - try p0.print(into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3 - ) -> ParserBuilder.ZipVVVV { - ParserBuilder.ZipVVVV(p0, p1, p2, p3) - } - } - - extension ParserBuilder { - public struct ZipOOOOO: Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P0.Output, - P1.Output, - P2.Output, - P3.Output, - P4.Output - ) { - do { - let o0 = try p0.parse(&input) - let o1 = try p1.parse(&input) - let o2 = try p2.parse(&input) - let o3 = try p3.parse(&input) - let o4 = try p4.parse(&input) - return (o0, o1, o2, o3, o4) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipOOOOO: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input - { - @inlinable public func print( - _ output: ( - P0.Output, - P1.Output, - P2.Output, - P3.Output, - P4.Output - ), - into input: inout P0.Input - ) rethrows { - try p4.print(output.4, into: &input) - try p3.print(output.3, into: &input) - try p2.print(output.2, into: &input) - try p1.print(output.1, into: &input) - try p0.print(output.0, into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4 - ) -> ParserBuilder.ZipOOOOO { - ParserBuilder.ZipOOOOO(p0, p1, p2, p3, p4) - } - } - - extension ParserBuilder { - public struct ZipOOOOV: Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P0.Output, - P1.Output, - P2.Output, - P3.Output - ) { - do { - let o0 = try p0.parse(&input) - let o1 = try p1.parse(&input) - let o2 = try p2.parse(&input) - let o3 = try p3.parse(&input) - try p4.parse(&input) - return (o0, o1, o2, o3) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipOOOOV: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Output == Void - { - @inlinable public func print( - _ output: ( - P0.Output, - P1.Output, - P2.Output, - P3.Output - ), - into input: inout P0.Input - ) rethrows { - try p4.print(into: &input) - try p3.print(output.3, into: &input) - try p2.print(output.2, into: &input) - try p1.print(output.1, into: &input) - try p0.print(output.0, into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4 - ) -> ParserBuilder.ZipOOOOV { - ParserBuilder.ZipOOOOV(p0, p1, p2, p3, p4) - } - } - - extension ParserBuilder { - public struct ZipOOOVO: Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P3.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P0.Output, - P1.Output, - P2.Output, - P4.Output - ) { - do { - let o0 = try p0.parse(&input) - let o1 = try p1.parse(&input) - let o2 = try p2.parse(&input) - try p3.parse(&input) - let o4 = try p4.parse(&input) - return (o0, o1, o2, o4) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipOOOVO: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P3.Output == Void - { - @inlinable public func print( - _ output: ( - P0.Output, - P1.Output, - P2.Output, - P4.Output - ), - into input: inout P0.Input - ) rethrows { - try p4.print(output.3, into: &input) - try p3.print(into: &input) - try p2.print(output.2, into: &input) - try p1.print(output.1, into: &input) - try p0.print(output.0, into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4 - ) -> ParserBuilder.ZipOOOVO { - ParserBuilder.ZipOOOVO(p0, p1, p2, p3, p4) - } - } - - extension ParserBuilder { - public struct ZipOOOVV: Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P3.Output == Void, - P4.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P0.Output, - P1.Output, - P2.Output - ) { - do { - let o0 = try p0.parse(&input) - let o1 = try p1.parse(&input) - let o2 = try p2.parse(&input) - try p3.parse(&input) - try p4.parse(&input) - return (o0, o1, o2) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipOOOVV: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P3.Output == Void, - P4.Output == Void - { - @inlinable public func print( - _ output: ( - P0.Output, - P1.Output, - P2.Output - ), - into input: inout P0.Input - ) rethrows { - try p4.print(into: &input) - try p3.print(into: &input) - try p2.print(output.2, into: &input) - try p1.print(output.1, into: &input) - try p0.print(output.0, into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4 - ) -> ParserBuilder.ZipOOOVV { - ParserBuilder.ZipOOOVV(p0, p1, p2, p3, p4) - } - } - - extension ParserBuilder { - public struct ZipOOVOO: Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P2.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P0.Output, - P1.Output, - P3.Output, - P4.Output - ) { - do { - let o0 = try p0.parse(&input) - let o1 = try p1.parse(&input) - try p2.parse(&input) - let o3 = try p3.parse(&input) - let o4 = try p4.parse(&input) - return (o0, o1, o3, o4) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipOOVOO: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P2.Output == Void - { - @inlinable public func print( - _ output: ( - P0.Output, - P1.Output, - P3.Output, - P4.Output - ), - into input: inout P0.Input - ) rethrows { - try p4.print(output.3, into: &input) - try p3.print(output.2, into: &input) - try p2.print(into: &input) - try p1.print(output.1, into: &input) - try p0.print(output.0, into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4 - ) -> ParserBuilder.ZipOOVOO { - ParserBuilder.ZipOOVOO(p0, p1, p2, p3, p4) - } - } - - extension ParserBuilder { - public struct ZipOOVOV: Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P2.Output == Void, - P4.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P0.Output, - P1.Output, - P3.Output - ) { - do { - let o0 = try p0.parse(&input) - let o1 = try p1.parse(&input) - try p2.parse(&input) - let o3 = try p3.parse(&input) - try p4.parse(&input) - return (o0, o1, o3) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipOOVOV: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P2.Output == Void, - P4.Output == Void - { - @inlinable public func print( - _ output: ( - P0.Output, - P1.Output, - P3.Output - ), - into input: inout P0.Input - ) rethrows { - try p4.print(into: &input) - try p3.print(output.2, into: &input) - try p2.print(into: &input) - try p1.print(output.1, into: &input) - try p0.print(output.0, into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4 - ) -> ParserBuilder.ZipOOVOV { - ParserBuilder.ZipOOVOV(p0, p1, p2, p3, p4) - } - } - - extension ParserBuilder { - public struct ZipOOVVO: Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P2.Output == Void, - P3.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P0.Output, - P1.Output, - P4.Output - ) { - do { - let o0 = try p0.parse(&input) - let o1 = try p1.parse(&input) - try p2.parse(&input) - try p3.parse(&input) - let o4 = try p4.parse(&input) - return (o0, o1, o4) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipOOVVO: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P2.Output == Void, - P3.Output == Void - { - @inlinable public func print( - _ output: ( - P0.Output, - P1.Output, - P4.Output - ), - into input: inout P0.Input - ) rethrows { - try p4.print(output.2, into: &input) - try p3.print(into: &input) - try p2.print(into: &input) - try p1.print(output.1, into: &input) - try p0.print(output.0, into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4 - ) -> ParserBuilder.ZipOOVVO { - ParserBuilder.ZipOOVVO(p0, p1, p2, p3, p4) - } - } - - extension ParserBuilder { - public struct ZipOOVVV: Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P2.Output == Void, - P3.Output == Void, - P4.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P0.Output, - P1.Output - ) { - do { - let o0 = try p0.parse(&input) - let o1 = try p1.parse(&input) - try p2.parse(&input) - try p3.parse(&input) - try p4.parse(&input) - return (o0, o1) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipOOVVV: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P2.Output == Void, - P3.Output == Void, - P4.Output == Void - { - @inlinable public func print( - _ output: ( - P0.Output, - P1.Output - ), - into input: inout P0.Input - ) rethrows { - try p4.print(into: &input) - try p3.print(into: &input) - try p2.print(into: &input) - try p1.print(output.1, into: &input) - try p0.print(output.0, into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4 - ) -> ParserBuilder.ZipOOVVV { - ParserBuilder.ZipOOVVV(p0, p1, p2, p3, p4) - } - } - - extension ParserBuilder { - public struct ZipOVOOO: Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P1.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P0.Output, - P2.Output, - P3.Output, - P4.Output - ) { - do { - let o0 = try p0.parse(&input) - try p1.parse(&input) - let o2 = try p2.parse(&input) - let o3 = try p3.parse(&input) - let o4 = try p4.parse(&input) - return (o0, o2, o3, o4) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipOVOOO: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P1.Output == Void - { - @inlinable public func print( - _ output: ( - P0.Output, - P2.Output, - P3.Output, - P4.Output - ), - into input: inout P0.Input - ) rethrows { - try p4.print(output.3, into: &input) - try p3.print(output.2, into: &input) - try p2.print(output.1, into: &input) - try p1.print(into: &input) - try p0.print(output.0, into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4 - ) -> ParserBuilder.ZipOVOOO { - ParserBuilder.ZipOVOOO(p0, p1, p2, p3, p4) - } - } - - extension ParserBuilder { - public struct ZipOVOOV: Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P1.Output == Void, - P4.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P0.Output, - P2.Output, - P3.Output - ) { - do { - let o0 = try p0.parse(&input) - try p1.parse(&input) - let o2 = try p2.parse(&input) - let o3 = try p3.parse(&input) - try p4.parse(&input) - return (o0, o2, o3) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipOVOOV: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P1.Output == Void, - P4.Output == Void - { - @inlinable public func print( - _ output: ( - P0.Output, - P2.Output, - P3.Output - ), - into input: inout P0.Input - ) rethrows { - try p4.print(into: &input) - try p3.print(output.2, into: &input) - try p2.print(output.1, into: &input) - try p1.print(into: &input) - try p0.print(output.0, into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4 - ) -> ParserBuilder.ZipOVOOV { - ParserBuilder.ZipOVOOV(p0, p1, p2, p3, p4) - } - } - - extension ParserBuilder { - public struct ZipOVOVO: Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P1.Output == Void, - P3.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P0.Output, - P2.Output, - P4.Output - ) { - do { - let o0 = try p0.parse(&input) - try p1.parse(&input) - let o2 = try p2.parse(&input) - try p3.parse(&input) - let o4 = try p4.parse(&input) - return (o0, o2, o4) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipOVOVO: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P1.Output == Void, - P3.Output == Void - { - @inlinable public func print( - _ output: ( - P0.Output, - P2.Output, - P4.Output - ), - into input: inout P0.Input - ) rethrows { - try p4.print(output.2, into: &input) - try p3.print(into: &input) - try p2.print(output.1, into: &input) - try p1.print(into: &input) - try p0.print(output.0, into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4 - ) -> ParserBuilder.ZipOVOVO { - ParserBuilder.ZipOVOVO(p0, p1, p2, p3, p4) - } - } - - extension ParserBuilder { - public struct ZipOVOVV: Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P1.Output == Void, - P3.Output == Void, - P4.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P0.Output, - P2.Output - ) { - do { - let o0 = try p0.parse(&input) - try p1.parse(&input) - let o2 = try p2.parse(&input) - try p3.parse(&input) - try p4.parse(&input) - return (o0, o2) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipOVOVV: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P1.Output == Void, - P3.Output == Void, - P4.Output == Void - { - @inlinable public func print( - _ output: ( - P0.Output, - P2.Output - ), - into input: inout P0.Input - ) rethrows { - try p4.print(into: &input) - try p3.print(into: &input) - try p2.print(output.1, into: &input) - try p1.print(into: &input) - try p0.print(output.0, into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4 - ) -> ParserBuilder.ZipOVOVV { - ParserBuilder.ZipOVOVV(p0, p1, p2, p3, p4) - } - } - - extension ParserBuilder { - public struct ZipOVVOO: Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P1.Output == Void, - P2.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P0.Output, - P3.Output, - P4.Output - ) { - do { - let o0 = try p0.parse(&input) - try p1.parse(&input) - try p2.parse(&input) - let o3 = try p3.parse(&input) - let o4 = try p4.parse(&input) - return (o0, o3, o4) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipOVVOO: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P1.Output == Void, - P2.Output == Void - { - @inlinable public func print( - _ output: ( - P0.Output, - P3.Output, - P4.Output - ), - into input: inout P0.Input - ) rethrows { - try p4.print(output.2, into: &input) - try p3.print(output.1, into: &input) - try p2.print(into: &input) - try p1.print(into: &input) - try p0.print(output.0, into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4 - ) -> ParserBuilder.ZipOVVOO { - ParserBuilder.ZipOVVOO(p0, p1, p2, p3, p4) - } - } - - extension ParserBuilder { - public struct ZipOVVOV: Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P1.Output == Void, - P2.Output == Void, - P4.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P0.Output, - P3.Output - ) { - do { - let o0 = try p0.parse(&input) - try p1.parse(&input) - try p2.parse(&input) - let o3 = try p3.parse(&input) - try p4.parse(&input) - return (o0, o3) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipOVVOV: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P1.Output == Void, - P2.Output == Void, - P4.Output == Void - { - @inlinable public func print( - _ output: ( - P0.Output, - P3.Output - ), - into input: inout P0.Input - ) rethrows { - try p4.print(into: &input) - try p3.print(output.1, into: &input) - try p2.print(into: &input) - try p1.print(into: &input) - try p0.print(output.0, into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4 - ) -> ParserBuilder.ZipOVVOV { - ParserBuilder.ZipOVVOV(p0, p1, p2, p3, p4) - } - } - - extension ParserBuilder { - public struct ZipOVVVO: Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P1.Output == Void, - P2.Output == Void, - P3.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P0.Output, - P4.Output - ) { - do { - let o0 = try p0.parse(&input) - try p1.parse(&input) - try p2.parse(&input) - try p3.parse(&input) - let o4 = try p4.parse(&input) - return (o0, o4) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipOVVVO: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P1.Output == Void, - P2.Output == Void, - P3.Output == Void - { - @inlinable public func print( - _ output: ( - P0.Output, - P4.Output - ), - into input: inout P0.Input - ) rethrows { - try p4.print(output.1, into: &input) - try p3.print(into: &input) - try p2.print(into: &input) - try p1.print(into: &input) - try p0.print(output.0, into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4 - ) -> ParserBuilder.ZipOVVVO { - ParserBuilder.ZipOVVVO(p0, p1, p2, p3, p4) - } - } - - extension ParserBuilder { - public struct ZipOVVVV: Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P1.Output == Void, - P2.Output == Void, - P3.Output == Void, - P4.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> P0.Output { - do { - let o0 = try p0.parse(&input) - try p1.parse(&input) - try p2.parse(&input) - try p3.parse(&input) - try p4.parse(&input) - return o0 - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipOVVVV: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P1.Output == Void, - P2.Output == Void, - P3.Output == Void, - P4.Output == Void - { - @inlinable public func print( - _ output: P0.Output, - into input: inout P0.Input - ) rethrows { - try p4.print(into: &input) - try p3.print(into: &input) - try p2.print(into: &input) - try p1.print(into: &input) - try p0.print(output, into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4 - ) -> ParserBuilder.ZipOVVVV { - ParserBuilder.ZipOVVVV(p0, p1, p2, p3, p4) - } - } - - extension ParserBuilder { - public struct ZipVOOOO: Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P0.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P1.Output, - P2.Output, - P3.Output, - P4.Output - ) { - do { - try p0.parse(&input) - let o1 = try p1.parse(&input) - let o2 = try p2.parse(&input) - let o3 = try p3.parse(&input) - let o4 = try p4.parse(&input) - return (o1, o2, o3, o4) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipVOOOO: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P0.Output == Void - { - @inlinable public func print( - _ output: ( - P1.Output, - P2.Output, - P3.Output, - P4.Output - ), - into input: inout P0.Input - ) rethrows { - try p4.print(output.3, into: &input) - try p3.print(output.2, into: &input) - try p2.print(output.1, into: &input) - try p1.print(output.0, into: &input) - try p0.print(into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4 - ) -> ParserBuilder.ZipVOOOO { - ParserBuilder.ZipVOOOO(p0, p1, p2, p3, p4) - } - } - - extension ParserBuilder { - public struct ZipVOOOV: Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P0.Output == Void, - P4.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P1.Output, - P2.Output, - P3.Output - ) { - do { - try p0.parse(&input) - let o1 = try p1.parse(&input) - let o2 = try p2.parse(&input) - let o3 = try p3.parse(&input) - try p4.parse(&input) - return (o1, o2, o3) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipVOOOV: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P0.Output == Void, - P4.Output == Void - { - @inlinable public func print( - _ output: ( - P1.Output, - P2.Output, - P3.Output - ), - into input: inout P0.Input - ) rethrows { - try p4.print(into: &input) - try p3.print(output.2, into: &input) - try p2.print(output.1, into: &input) - try p1.print(output.0, into: &input) - try p0.print(into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4 - ) -> ParserBuilder.ZipVOOOV { - ParserBuilder.ZipVOOOV(p0, p1, p2, p3, p4) - } - } - - extension ParserBuilder { - public struct ZipVOOVO: Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P0.Output == Void, - P3.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P1.Output, - P2.Output, - P4.Output - ) { - do { - try p0.parse(&input) - let o1 = try p1.parse(&input) - let o2 = try p2.parse(&input) - try p3.parse(&input) - let o4 = try p4.parse(&input) - return (o1, o2, o4) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipVOOVO: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P0.Output == Void, - P3.Output == Void - { - @inlinable public func print( - _ output: ( - P1.Output, - P2.Output, - P4.Output - ), - into input: inout P0.Input - ) rethrows { - try p4.print(output.2, into: &input) - try p3.print(into: &input) - try p2.print(output.1, into: &input) - try p1.print(output.0, into: &input) - try p0.print(into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4 - ) -> ParserBuilder.ZipVOOVO { - ParserBuilder.ZipVOOVO(p0, p1, p2, p3, p4) - } - } - - extension ParserBuilder { - public struct ZipVOOVV: Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P0.Output == Void, - P3.Output == Void, - P4.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P1.Output, - P2.Output - ) { - do { - try p0.parse(&input) - let o1 = try p1.parse(&input) - let o2 = try p2.parse(&input) - try p3.parse(&input) - try p4.parse(&input) - return (o1, o2) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipVOOVV: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P0.Output == Void, - P3.Output == Void, - P4.Output == Void - { - @inlinable public func print( - _ output: ( - P1.Output, - P2.Output - ), - into input: inout P0.Input - ) rethrows { - try p4.print(into: &input) - try p3.print(into: &input) - try p2.print(output.1, into: &input) - try p1.print(output.0, into: &input) - try p0.print(into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4 - ) -> ParserBuilder.ZipVOOVV { - ParserBuilder.ZipVOOVV(p0, p1, p2, p3, p4) - } - } - - extension ParserBuilder { - public struct ZipVOVOO: Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P0.Output == Void, - P2.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P1.Output, - P3.Output, - P4.Output - ) { - do { - try p0.parse(&input) - let o1 = try p1.parse(&input) - try p2.parse(&input) - let o3 = try p3.parse(&input) - let o4 = try p4.parse(&input) - return (o1, o3, o4) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipVOVOO: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P0.Output == Void, - P2.Output == Void - { - @inlinable public func print( - _ output: ( - P1.Output, - P3.Output, - P4.Output - ), - into input: inout P0.Input - ) rethrows { - try p4.print(output.2, into: &input) - try p3.print(output.1, into: &input) - try p2.print(into: &input) - try p1.print(output.0, into: &input) - try p0.print(into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4 - ) -> ParserBuilder.ZipVOVOO { - ParserBuilder.ZipVOVOO(p0, p1, p2, p3, p4) - } - } - - extension ParserBuilder { - public struct ZipVOVOV: Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P0.Output == Void, - P2.Output == Void, - P4.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P1.Output, - P3.Output - ) { - do { - try p0.parse(&input) - let o1 = try p1.parse(&input) - try p2.parse(&input) - let o3 = try p3.parse(&input) - try p4.parse(&input) - return (o1, o3) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipVOVOV: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P0.Output == Void, - P2.Output == Void, - P4.Output == Void - { - @inlinable public func print( - _ output: ( - P1.Output, - P3.Output - ), - into input: inout P0.Input - ) rethrows { - try p4.print(into: &input) - try p3.print(output.1, into: &input) - try p2.print(into: &input) - try p1.print(output.0, into: &input) - try p0.print(into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4 - ) -> ParserBuilder.ZipVOVOV { - ParserBuilder.ZipVOVOV(p0, p1, p2, p3, p4) - } - } - - extension ParserBuilder { - public struct ZipVOVVO: Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P0.Output == Void, - P2.Output == Void, - P3.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P1.Output, - P4.Output - ) { - do { - try p0.parse(&input) - let o1 = try p1.parse(&input) - try p2.parse(&input) - try p3.parse(&input) - let o4 = try p4.parse(&input) - return (o1, o4) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipVOVVO: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P0.Output == Void, - P2.Output == Void, - P3.Output == Void - { - @inlinable public func print( - _ output: ( - P1.Output, - P4.Output - ), - into input: inout P0.Input - ) rethrows { - try p4.print(output.1, into: &input) - try p3.print(into: &input) - try p2.print(into: &input) - try p1.print(output.0, into: &input) - try p0.print(into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4 - ) -> ParserBuilder.ZipVOVVO { - ParserBuilder.ZipVOVVO(p0, p1, p2, p3, p4) - } - } - - extension ParserBuilder { - public struct ZipVOVVV: Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P0.Output == Void, - P2.Output == Void, - P3.Output == Void, - P4.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> P1.Output { - do { - try p0.parse(&input) - let o1 = try p1.parse(&input) - try p2.parse(&input) - try p3.parse(&input) - try p4.parse(&input) - return o1 - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipVOVVV: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P0.Output == Void, - P2.Output == Void, - P3.Output == Void, - P4.Output == Void - { - @inlinable public func print( - _ output: P1.Output, - into input: inout P0.Input - ) rethrows { - try p4.print(into: &input) - try p3.print(into: &input) - try p2.print(into: &input) - try p1.print(output, into: &input) - try p0.print(into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4 - ) -> ParserBuilder.ZipVOVVV { - ParserBuilder.ZipVOVVV(p0, p1, p2, p3, p4) - } - } - - extension ParserBuilder { - public struct ZipVVOOO: Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P0.Output == Void, - P1.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P2.Output, - P3.Output, - P4.Output - ) { - do { - try p0.parse(&input) - try p1.parse(&input) - let o2 = try p2.parse(&input) - let o3 = try p3.parse(&input) - let o4 = try p4.parse(&input) - return (o2, o3, o4) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipVVOOO: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P0.Output == Void, - P1.Output == Void - { - @inlinable public func print( - _ output: ( - P2.Output, - P3.Output, - P4.Output - ), - into input: inout P0.Input - ) rethrows { - try p4.print(output.2, into: &input) - try p3.print(output.1, into: &input) - try p2.print(output.0, into: &input) - try p1.print(into: &input) - try p0.print(into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4 - ) -> ParserBuilder.ZipVVOOO { - ParserBuilder.ZipVVOOO(p0, p1, p2, p3, p4) - } - } - - extension ParserBuilder { - public struct ZipVVOOV: Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P0.Output == Void, - P1.Output == Void, - P4.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P2.Output, - P3.Output - ) { - do { - try p0.parse(&input) - try p1.parse(&input) - let o2 = try p2.parse(&input) - let o3 = try p3.parse(&input) - try p4.parse(&input) - return (o2, o3) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipVVOOV: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P0.Output == Void, - P1.Output == Void, - P4.Output == Void - { - @inlinable public func print( - _ output: ( - P2.Output, - P3.Output - ), - into input: inout P0.Input - ) rethrows { - try p4.print(into: &input) - try p3.print(output.1, into: &input) - try p2.print(output.0, into: &input) - try p1.print(into: &input) - try p0.print(into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4 - ) -> ParserBuilder.ZipVVOOV { - ParserBuilder.ZipVVOOV(p0, p1, p2, p3, p4) - } - } - - extension ParserBuilder { - public struct ZipVVOVO: Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P0.Output == Void, - P1.Output == Void, - P3.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P2.Output, - P4.Output - ) { - do { - try p0.parse(&input) - try p1.parse(&input) - let o2 = try p2.parse(&input) - try p3.parse(&input) - let o4 = try p4.parse(&input) - return (o2, o4) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipVVOVO: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P0.Output == Void, - P1.Output == Void, - P3.Output == Void - { - @inlinable public func print( - _ output: ( - P2.Output, - P4.Output - ), - into input: inout P0.Input - ) rethrows { - try p4.print(output.1, into: &input) - try p3.print(into: &input) - try p2.print(output.0, into: &input) - try p1.print(into: &input) - try p0.print(into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4 - ) -> ParserBuilder.ZipVVOVO { - ParserBuilder.ZipVVOVO(p0, p1, p2, p3, p4) - } - } - - extension ParserBuilder { - public struct ZipVVOVV: Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P0.Output == Void, - P1.Output == Void, - P3.Output == Void, - P4.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> P2.Output { - do { - try p0.parse(&input) - try p1.parse(&input) - let o2 = try p2.parse(&input) - try p3.parse(&input) - try p4.parse(&input) - return o2 - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipVVOVV: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P0.Output == Void, - P1.Output == Void, - P3.Output == Void, - P4.Output == Void - { - @inlinable public func print( - _ output: P2.Output, - into input: inout P0.Input - ) rethrows { - try p4.print(into: &input) - try p3.print(into: &input) - try p2.print(output, into: &input) - try p1.print(into: &input) - try p0.print(into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4 - ) -> ParserBuilder.ZipVVOVV { - ParserBuilder.ZipVVOVV(p0, p1, p2, p3, p4) - } - } - - extension ParserBuilder { - public struct ZipVVVOO: Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P0.Output == Void, - P1.Output == Void, - P2.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P3.Output, - P4.Output - ) { - do { - try p0.parse(&input) - try p1.parse(&input) - try p2.parse(&input) - let o3 = try p3.parse(&input) - let o4 = try p4.parse(&input) - return (o3, o4) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipVVVOO: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P0.Output == Void, - P1.Output == Void, - P2.Output == Void - { - @inlinable public func print( - _ output: ( - P3.Output, - P4.Output - ), - into input: inout P0.Input - ) rethrows { - try p4.print(output.1, into: &input) - try p3.print(output.0, into: &input) - try p2.print(into: &input) - try p1.print(into: &input) - try p0.print(into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4 - ) -> ParserBuilder.ZipVVVOO { - ParserBuilder.ZipVVVOO(p0, p1, p2, p3, p4) - } - } - - extension ParserBuilder { - public struct ZipVVVOV: Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P0.Output == Void, - P1.Output == Void, - P2.Output == Void, - P4.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> P3.Output { - do { - try p0.parse(&input) - try p1.parse(&input) - try p2.parse(&input) - let o3 = try p3.parse(&input) - try p4.parse(&input) - return o3 - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipVVVOV: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P0.Output == Void, - P1.Output == Void, - P2.Output == Void, - P4.Output == Void - { - @inlinable public func print( - _ output: P3.Output, - into input: inout P0.Input - ) rethrows { - try p4.print(into: &input) - try p3.print(output, into: &input) - try p2.print(into: &input) - try p1.print(into: &input) - try p0.print(into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4 - ) -> ParserBuilder.ZipVVVOV { - ParserBuilder.ZipVVVOV(p0, p1, p2, p3, p4) - } - } - - extension ParserBuilder { - public struct ZipVVVVO: Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P0.Output == Void, - P1.Output == Void, - P2.Output == Void, - P3.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> P4.Output { - do { - try p0.parse(&input) - try p1.parse(&input) - try p2.parse(&input) - try p3.parse(&input) - let o4 = try p4.parse(&input) - return o4 - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipVVVVO: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P0.Output == Void, - P1.Output == Void, - P2.Output == Void, - P3.Output == Void - { - @inlinable public func print( - _ output: P4.Output, - into input: inout P0.Input - ) rethrows { - try p4.print(output, into: &input) - try p3.print(into: &input) - try p2.print(into: &input) - try p1.print(into: &input) - try p0.print(into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4 - ) -> ParserBuilder.ZipVVVVO { - ParserBuilder.ZipVVVVO(p0, p1, p2, p3, p4) - } - } - - extension ParserBuilder { - public struct ZipVVVVV: Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P0.Output == Void, - P1.Output == Void, - P2.Output == Void, - P3.Output == Void, - P4.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows { - do { - try p0.parse(&input) - try p1.parse(&input) - try p2.parse(&input) - try p3.parse(&input) - try p4.parse(&input) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipVVVVV: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P0.Output == Void, - P1.Output == Void, - P2.Output == Void, - P3.Output == Void, - P4.Output == Void - { - @inlinable public func print( - _ output: Void, - into input: inout P0.Input - ) rethrows { - try p4.print(into: &input) - try p3.print(into: &input) - try p2.print(into: &input) - try p1.print(into: &input) - try p0.print(into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4 - ) -> ParserBuilder.ZipVVVVV { - ParserBuilder.ZipVVVVV(p0, p1, p2, p3, p4) - } - } - - extension ParserBuilder { - public struct ZipOOOOOO: - Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - self.p5 = p5 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P0.Output, - P1.Output, - P2.Output, - P3.Output, - P4.Output, - P5.Output - ) { - do { - let o0 = try p0.parse(&input) - let o1 = try p1.parse(&input) - let o2 = try p2.parse(&input) - let o3 = try p3.parse(&input) - let o4 = try p4.parse(&input) - let o5 = try p5.parse(&input) - return (o0, o1, o2, o3, o4, o5) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipOOOOOO: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P5: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input - { - @inlinable public func print( - _ output: ( - P0.Output, - P1.Output, - P2.Output, - P3.Output, - P4.Output, - P5.Output - ), - into input: inout P0.Input - ) rethrows { - try p5.print(output.5, into: &input) - try p4.print(output.4, into: &input) - try p3.print(output.3, into: &input) - try p2.print(output.2, into: &input) - try p1.print(output.1, into: &input) - try p0.print(output.0, into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 - ) -> ParserBuilder.ZipOOOOOO { - ParserBuilder.ZipOOOOOO(p0, p1, p2, p3, p4, p5) - } - } - - extension ParserBuilder { - public struct ZipOOOOOV: - Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P5.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - self.p5 = p5 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P0.Output, - P1.Output, - P2.Output, - P3.Output, - P4.Output - ) { - do { - let o0 = try p0.parse(&input) - let o1 = try p1.parse(&input) - let o2 = try p2.parse(&input) - let o3 = try p3.parse(&input) - let o4 = try p4.parse(&input) - try p5.parse(&input) - return (o0, o1, o2, o3, o4) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipOOOOOV: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P5: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P5.Output == Void - { - @inlinable public func print( - _ output: ( - P0.Output, - P1.Output, - P2.Output, - P3.Output, - P4.Output - ), - into input: inout P0.Input - ) rethrows { - try p5.print(into: &input) - try p4.print(output.4, into: &input) - try p3.print(output.3, into: &input) - try p2.print(output.2, into: &input) - try p1.print(output.1, into: &input) - try p0.print(output.0, into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 - ) -> ParserBuilder.ZipOOOOOV { - ParserBuilder.ZipOOOOOV(p0, p1, p2, p3, p4, p5) - } - } - - extension ParserBuilder { - public struct ZipOOOOVO: - Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P4.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - self.p5 = p5 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P0.Output, - P1.Output, - P2.Output, - P3.Output, - P5.Output - ) { - do { - let o0 = try p0.parse(&input) - let o1 = try p1.parse(&input) - let o2 = try p2.parse(&input) - let o3 = try p3.parse(&input) - try p4.parse(&input) - let o5 = try p5.parse(&input) - return (o0, o1, o2, o3, o5) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipOOOOVO: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P5: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P4.Output == Void - { - @inlinable public func print( - _ output: ( - P0.Output, - P1.Output, - P2.Output, - P3.Output, - P5.Output - ), - into input: inout P0.Input - ) rethrows { - try p5.print(output.4, into: &input) - try p4.print(into: &input) - try p3.print(output.3, into: &input) - try p2.print(output.2, into: &input) - try p1.print(output.1, into: &input) - try p0.print(output.0, into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 - ) -> ParserBuilder.ZipOOOOVO { - ParserBuilder.ZipOOOOVO(p0, p1, p2, p3, p4, p5) - } - } - - extension ParserBuilder { - public struct ZipOOOOVV: - Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P4.Output == Void, - P5.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - self.p5 = p5 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P0.Output, - P1.Output, - P2.Output, - P3.Output - ) { - do { - let o0 = try p0.parse(&input) - let o1 = try p1.parse(&input) - let o2 = try p2.parse(&input) - let o3 = try p3.parse(&input) - try p4.parse(&input) - try p5.parse(&input) - return (o0, o1, o2, o3) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipOOOOVV: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P5: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P4.Output == Void, - P5.Output == Void - { - @inlinable public func print( - _ output: ( - P0.Output, - P1.Output, - P2.Output, - P3.Output - ), - into input: inout P0.Input - ) rethrows { - try p5.print(into: &input) - try p4.print(into: &input) - try p3.print(output.3, into: &input) - try p2.print(output.2, into: &input) - try p1.print(output.1, into: &input) - try p0.print(output.0, into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 - ) -> ParserBuilder.ZipOOOOVV { - ParserBuilder.ZipOOOOVV(p0, p1, p2, p3, p4, p5) - } - } - - extension ParserBuilder { - public struct ZipOOOVOO: - Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P3.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - self.p5 = p5 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P0.Output, - P1.Output, - P2.Output, - P4.Output, - P5.Output - ) { - do { - let o0 = try p0.parse(&input) - let o1 = try p1.parse(&input) - let o2 = try p2.parse(&input) - try p3.parse(&input) - let o4 = try p4.parse(&input) - let o5 = try p5.parse(&input) - return (o0, o1, o2, o4, o5) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipOOOVOO: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P5: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P3.Output == Void - { - @inlinable public func print( - _ output: ( - P0.Output, - P1.Output, - P2.Output, - P4.Output, - P5.Output - ), - into input: inout P0.Input - ) rethrows { - try p5.print(output.4, into: &input) - try p4.print(output.3, into: &input) - try p3.print(into: &input) - try p2.print(output.2, into: &input) - try p1.print(output.1, into: &input) - try p0.print(output.0, into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 - ) -> ParserBuilder.ZipOOOVOO { - ParserBuilder.ZipOOOVOO(p0, p1, p2, p3, p4, p5) - } - } - - extension ParserBuilder { - public struct ZipOOOVOV: - Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P3.Output == Void, - P5.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - self.p5 = p5 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P0.Output, - P1.Output, - P2.Output, - P4.Output - ) { - do { - let o0 = try p0.parse(&input) - let o1 = try p1.parse(&input) - let o2 = try p2.parse(&input) - try p3.parse(&input) - let o4 = try p4.parse(&input) - try p5.parse(&input) - return (o0, o1, o2, o4) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipOOOVOV: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P5: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P3.Output == Void, - P5.Output == Void - { - @inlinable public func print( - _ output: ( - P0.Output, - P1.Output, - P2.Output, - P4.Output - ), - into input: inout P0.Input - ) rethrows { - try p5.print(into: &input) - try p4.print(output.3, into: &input) - try p3.print(into: &input) - try p2.print(output.2, into: &input) - try p1.print(output.1, into: &input) - try p0.print(output.0, into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 - ) -> ParserBuilder.ZipOOOVOV { - ParserBuilder.ZipOOOVOV(p0, p1, p2, p3, p4, p5) - } - } - - extension ParserBuilder { - public struct ZipOOOVVO: - Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P3.Output == Void, - P4.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - self.p5 = p5 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P0.Output, - P1.Output, - P2.Output, - P5.Output - ) { - do { - let o0 = try p0.parse(&input) - let o1 = try p1.parse(&input) - let o2 = try p2.parse(&input) - try p3.parse(&input) - try p4.parse(&input) - let o5 = try p5.parse(&input) - return (o0, o1, o2, o5) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipOOOVVO: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P5: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P3.Output == Void, - P4.Output == Void - { - @inlinable public func print( - _ output: ( - P0.Output, - P1.Output, - P2.Output, - P5.Output - ), - into input: inout P0.Input - ) rethrows { - try p5.print(output.3, into: &input) - try p4.print(into: &input) - try p3.print(into: &input) - try p2.print(output.2, into: &input) - try p1.print(output.1, into: &input) - try p0.print(output.0, into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 - ) -> ParserBuilder.ZipOOOVVO { - ParserBuilder.ZipOOOVVO(p0, p1, p2, p3, p4, p5) - } - } - - extension ParserBuilder { - public struct ZipOOOVVV: - Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P3.Output == Void, - P4.Output == Void, - P5.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - self.p5 = p5 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P0.Output, - P1.Output, - P2.Output - ) { - do { - let o0 = try p0.parse(&input) - let o1 = try p1.parse(&input) - let o2 = try p2.parse(&input) - try p3.parse(&input) - try p4.parse(&input) - try p5.parse(&input) - return (o0, o1, o2) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipOOOVVV: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P5: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P3.Output == Void, - P4.Output == Void, - P5.Output == Void - { - @inlinable public func print( - _ output: ( - P0.Output, - P1.Output, - P2.Output - ), - into input: inout P0.Input - ) rethrows { - try p5.print(into: &input) - try p4.print(into: &input) - try p3.print(into: &input) - try p2.print(output.2, into: &input) - try p1.print(output.1, into: &input) - try p0.print(output.0, into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 - ) -> ParserBuilder.ZipOOOVVV { - ParserBuilder.ZipOOOVVV(p0, p1, p2, p3, p4, p5) - } - } - - extension ParserBuilder { - public struct ZipOOVOOO: - Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P2.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - self.p5 = p5 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P0.Output, - P1.Output, - P3.Output, - P4.Output, - P5.Output - ) { - do { - let o0 = try p0.parse(&input) - let o1 = try p1.parse(&input) - try p2.parse(&input) - let o3 = try p3.parse(&input) - let o4 = try p4.parse(&input) - let o5 = try p5.parse(&input) - return (o0, o1, o3, o4, o5) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipOOVOOO: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P5: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P2.Output == Void - { - @inlinable public func print( - _ output: ( - P0.Output, - P1.Output, - P3.Output, - P4.Output, - P5.Output - ), - into input: inout P0.Input - ) rethrows { - try p5.print(output.4, into: &input) - try p4.print(output.3, into: &input) - try p3.print(output.2, into: &input) - try p2.print(into: &input) - try p1.print(output.1, into: &input) - try p0.print(output.0, into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 - ) -> ParserBuilder.ZipOOVOOO { - ParserBuilder.ZipOOVOOO(p0, p1, p2, p3, p4, p5) - } - } - - extension ParserBuilder { - public struct ZipOOVOOV: - Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P2.Output == Void, - P5.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - self.p5 = p5 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P0.Output, - P1.Output, - P3.Output, - P4.Output - ) { - do { - let o0 = try p0.parse(&input) - let o1 = try p1.parse(&input) - try p2.parse(&input) - let o3 = try p3.parse(&input) - let o4 = try p4.parse(&input) - try p5.parse(&input) - return (o0, o1, o3, o4) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipOOVOOV: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P5: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P2.Output == Void, - P5.Output == Void - { - @inlinable public func print( - _ output: ( - P0.Output, - P1.Output, - P3.Output, - P4.Output - ), - into input: inout P0.Input - ) rethrows { - try p5.print(into: &input) - try p4.print(output.3, into: &input) - try p3.print(output.2, into: &input) - try p2.print(into: &input) - try p1.print(output.1, into: &input) - try p0.print(output.0, into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 - ) -> ParserBuilder.ZipOOVOOV { - ParserBuilder.ZipOOVOOV(p0, p1, p2, p3, p4, p5) - } - } - - extension ParserBuilder { - public struct ZipOOVOVO: - Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P2.Output == Void, - P4.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - self.p5 = p5 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P0.Output, - P1.Output, - P3.Output, - P5.Output - ) { - do { - let o0 = try p0.parse(&input) - let o1 = try p1.parse(&input) - try p2.parse(&input) - let o3 = try p3.parse(&input) - try p4.parse(&input) - let o5 = try p5.parse(&input) - return (o0, o1, o3, o5) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipOOVOVO: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P5: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P2.Output == Void, - P4.Output == Void - { - @inlinable public func print( - _ output: ( - P0.Output, - P1.Output, - P3.Output, - P5.Output - ), - into input: inout P0.Input - ) rethrows { - try p5.print(output.3, into: &input) - try p4.print(into: &input) - try p3.print(output.2, into: &input) - try p2.print(into: &input) - try p1.print(output.1, into: &input) - try p0.print(output.0, into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 - ) -> ParserBuilder.ZipOOVOVO { - ParserBuilder.ZipOOVOVO(p0, p1, p2, p3, p4, p5) - } - } - - extension ParserBuilder { - public struct ZipOOVOVV: - Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P2.Output == Void, - P4.Output == Void, - P5.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - self.p5 = p5 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P0.Output, - P1.Output, - P3.Output - ) { - do { - let o0 = try p0.parse(&input) - let o1 = try p1.parse(&input) - try p2.parse(&input) - let o3 = try p3.parse(&input) - try p4.parse(&input) - try p5.parse(&input) - return (o0, o1, o3) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipOOVOVV: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P5: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P2.Output == Void, - P4.Output == Void, - P5.Output == Void - { - @inlinable public func print( - _ output: ( - P0.Output, - P1.Output, - P3.Output - ), - into input: inout P0.Input - ) rethrows { - try p5.print(into: &input) - try p4.print(into: &input) - try p3.print(output.2, into: &input) - try p2.print(into: &input) - try p1.print(output.1, into: &input) - try p0.print(output.0, into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 - ) -> ParserBuilder.ZipOOVOVV { - ParserBuilder.ZipOOVOVV(p0, p1, p2, p3, p4, p5) - } - } - - extension ParserBuilder { - public struct ZipOOVVOO: - Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P2.Output == Void, - P3.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - self.p5 = p5 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P0.Output, - P1.Output, - P4.Output, - P5.Output - ) { - do { - let o0 = try p0.parse(&input) - let o1 = try p1.parse(&input) - try p2.parse(&input) - try p3.parse(&input) - let o4 = try p4.parse(&input) - let o5 = try p5.parse(&input) - return (o0, o1, o4, o5) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipOOVVOO: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P5: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P2.Output == Void, - P3.Output == Void - { - @inlinable public func print( - _ output: ( - P0.Output, - P1.Output, - P4.Output, - P5.Output - ), - into input: inout P0.Input - ) rethrows { - try p5.print(output.3, into: &input) - try p4.print(output.2, into: &input) - try p3.print(into: &input) - try p2.print(into: &input) - try p1.print(output.1, into: &input) - try p0.print(output.0, into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 - ) -> ParserBuilder.ZipOOVVOO { - ParserBuilder.ZipOOVVOO(p0, p1, p2, p3, p4, p5) - } - } - - extension ParserBuilder { - public struct ZipOOVVOV: - Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P2.Output == Void, - P3.Output == Void, - P5.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - self.p5 = p5 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P0.Output, - P1.Output, - P4.Output - ) { - do { - let o0 = try p0.parse(&input) - let o1 = try p1.parse(&input) - try p2.parse(&input) - try p3.parse(&input) - let o4 = try p4.parse(&input) - try p5.parse(&input) - return (o0, o1, o4) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipOOVVOV: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P5: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P2.Output == Void, - P3.Output == Void, - P5.Output == Void - { - @inlinable public func print( - _ output: ( - P0.Output, - P1.Output, - P4.Output - ), - into input: inout P0.Input - ) rethrows { - try p5.print(into: &input) - try p4.print(output.2, into: &input) - try p3.print(into: &input) - try p2.print(into: &input) - try p1.print(output.1, into: &input) - try p0.print(output.0, into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 - ) -> ParserBuilder.ZipOOVVOV { - ParserBuilder.ZipOOVVOV(p0, p1, p2, p3, p4, p5) - } - } - - extension ParserBuilder { - public struct ZipOOVVVO: - Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P2.Output == Void, - P3.Output == Void, - P4.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - self.p5 = p5 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P0.Output, - P1.Output, - P5.Output - ) { - do { - let o0 = try p0.parse(&input) - let o1 = try p1.parse(&input) - try p2.parse(&input) - try p3.parse(&input) - try p4.parse(&input) - let o5 = try p5.parse(&input) - return (o0, o1, o5) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipOOVVVO: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P5: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P2.Output == Void, - P3.Output == Void, - P4.Output == Void - { - @inlinable public func print( - _ output: ( - P0.Output, - P1.Output, - P5.Output - ), - into input: inout P0.Input - ) rethrows { - try p5.print(output.2, into: &input) - try p4.print(into: &input) - try p3.print(into: &input) - try p2.print(into: &input) - try p1.print(output.1, into: &input) - try p0.print(output.0, into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 - ) -> ParserBuilder.ZipOOVVVO { - ParserBuilder.ZipOOVVVO(p0, p1, p2, p3, p4, p5) - } - } - - extension ParserBuilder { - public struct ZipOOVVVV: - Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P2.Output == Void, - P3.Output == Void, - P4.Output == Void, - P5.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - self.p5 = p5 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P0.Output, - P1.Output - ) { - do { - let o0 = try p0.parse(&input) - let o1 = try p1.parse(&input) - try p2.parse(&input) - try p3.parse(&input) - try p4.parse(&input) - try p5.parse(&input) - return (o0, o1) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipOOVVVV: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P5: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P2.Output == Void, - P3.Output == Void, - P4.Output == Void, - P5.Output == Void - { - @inlinable public func print( - _ output: ( - P0.Output, - P1.Output - ), - into input: inout P0.Input - ) rethrows { - try p5.print(into: &input) - try p4.print(into: &input) - try p3.print(into: &input) - try p2.print(into: &input) - try p1.print(output.1, into: &input) - try p0.print(output.0, into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 - ) -> ParserBuilder.ZipOOVVVV { - ParserBuilder.ZipOOVVVV(p0, p1, p2, p3, p4, p5) - } - } - - extension ParserBuilder { - public struct ZipOVOOOO: - Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P1.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - self.p5 = p5 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P0.Output, - P2.Output, - P3.Output, - P4.Output, - P5.Output - ) { - do { - let o0 = try p0.parse(&input) - try p1.parse(&input) - let o2 = try p2.parse(&input) - let o3 = try p3.parse(&input) - let o4 = try p4.parse(&input) - let o5 = try p5.parse(&input) - return (o0, o2, o3, o4, o5) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipOVOOOO: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P5: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P1.Output == Void - { - @inlinable public func print( - _ output: ( - P0.Output, - P2.Output, - P3.Output, - P4.Output, - P5.Output - ), - into input: inout P0.Input - ) rethrows { - try p5.print(output.4, into: &input) - try p4.print(output.3, into: &input) - try p3.print(output.2, into: &input) - try p2.print(output.1, into: &input) - try p1.print(into: &input) - try p0.print(output.0, into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 - ) -> ParserBuilder.ZipOVOOOO { - ParserBuilder.ZipOVOOOO(p0, p1, p2, p3, p4, p5) - } - } - - extension ParserBuilder { - public struct ZipOVOOOV: - Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P1.Output == Void, - P5.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - self.p5 = p5 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P0.Output, - P2.Output, - P3.Output, - P4.Output - ) { - do { - let o0 = try p0.parse(&input) - try p1.parse(&input) - let o2 = try p2.parse(&input) - let o3 = try p3.parse(&input) - let o4 = try p4.parse(&input) - try p5.parse(&input) - return (o0, o2, o3, o4) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipOVOOOV: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P5: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P1.Output == Void, - P5.Output == Void - { - @inlinable public func print( - _ output: ( - P0.Output, - P2.Output, - P3.Output, - P4.Output - ), - into input: inout P0.Input - ) rethrows { - try p5.print(into: &input) - try p4.print(output.3, into: &input) - try p3.print(output.2, into: &input) - try p2.print(output.1, into: &input) - try p1.print(into: &input) - try p0.print(output.0, into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 - ) -> ParserBuilder.ZipOVOOOV { - ParserBuilder.ZipOVOOOV(p0, p1, p2, p3, p4, p5) - } - } - - extension ParserBuilder { - public struct ZipOVOOVO: - Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P1.Output == Void, - P4.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - self.p5 = p5 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P0.Output, - P2.Output, - P3.Output, - P5.Output - ) { - do { - let o0 = try p0.parse(&input) - try p1.parse(&input) - let o2 = try p2.parse(&input) - let o3 = try p3.parse(&input) - try p4.parse(&input) - let o5 = try p5.parse(&input) - return (o0, o2, o3, o5) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipOVOOVO: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P5: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P1.Output == Void, - P4.Output == Void - { - @inlinable public func print( - _ output: ( - P0.Output, - P2.Output, - P3.Output, - P5.Output - ), - into input: inout P0.Input - ) rethrows { - try p5.print(output.3, into: &input) - try p4.print(into: &input) - try p3.print(output.2, into: &input) - try p2.print(output.1, into: &input) - try p1.print(into: &input) - try p0.print(output.0, into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 - ) -> ParserBuilder.ZipOVOOVO { - ParserBuilder.ZipOVOOVO(p0, p1, p2, p3, p4, p5) - } - } - - extension ParserBuilder { - public struct ZipOVOOVV: - Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P1.Output == Void, - P4.Output == Void, - P5.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - self.p5 = p5 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P0.Output, - P2.Output, - P3.Output - ) { - do { - let o0 = try p0.parse(&input) - try p1.parse(&input) - let o2 = try p2.parse(&input) - let o3 = try p3.parse(&input) - try p4.parse(&input) - try p5.parse(&input) - return (o0, o2, o3) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipOVOOVV: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P5: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P1.Output == Void, - P4.Output == Void, - P5.Output == Void - { - @inlinable public func print( - _ output: ( - P0.Output, - P2.Output, - P3.Output - ), - into input: inout P0.Input - ) rethrows { - try p5.print(into: &input) - try p4.print(into: &input) - try p3.print(output.2, into: &input) - try p2.print(output.1, into: &input) - try p1.print(into: &input) - try p0.print(output.0, into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 - ) -> ParserBuilder.ZipOVOOVV { - ParserBuilder.ZipOVOOVV(p0, p1, p2, p3, p4, p5) - } - } - - extension ParserBuilder { - public struct ZipOVOVOO: - Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P1.Output == Void, - P3.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - self.p5 = p5 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P0.Output, - P2.Output, - P4.Output, - P5.Output - ) { - do { - let o0 = try p0.parse(&input) - try p1.parse(&input) - let o2 = try p2.parse(&input) - try p3.parse(&input) - let o4 = try p4.parse(&input) - let o5 = try p5.parse(&input) - return (o0, o2, o4, o5) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipOVOVOO: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P5: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P1.Output == Void, - P3.Output == Void - { - @inlinable public func print( - _ output: ( - P0.Output, - P2.Output, - P4.Output, - P5.Output - ), - into input: inout P0.Input - ) rethrows { - try p5.print(output.3, into: &input) - try p4.print(output.2, into: &input) - try p3.print(into: &input) - try p2.print(output.1, into: &input) - try p1.print(into: &input) - try p0.print(output.0, into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 - ) -> ParserBuilder.ZipOVOVOO { - ParserBuilder.ZipOVOVOO(p0, p1, p2, p3, p4, p5) - } - } - - extension ParserBuilder { - public struct ZipOVOVOV: - Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P1.Output == Void, - P3.Output == Void, - P5.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - self.p5 = p5 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P0.Output, - P2.Output, - P4.Output - ) { - do { - let o0 = try p0.parse(&input) - try p1.parse(&input) - let o2 = try p2.parse(&input) - try p3.parse(&input) - let o4 = try p4.parse(&input) - try p5.parse(&input) - return (o0, o2, o4) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipOVOVOV: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P5: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P1.Output == Void, - P3.Output == Void, - P5.Output == Void - { - @inlinable public func print( - _ output: ( - P0.Output, - P2.Output, - P4.Output - ), - into input: inout P0.Input - ) rethrows { - try p5.print(into: &input) - try p4.print(output.2, into: &input) - try p3.print(into: &input) - try p2.print(output.1, into: &input) - try p1.print(into: &input) - try p0.print(output.0, into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 - ) -> ParserBuilder.ZipOVOVOV { - ParserBuilder.ZipOVOVOV(p0, p1, p2, p3, p4, p5) - } - } - - extension ParserBuilder { - public struct ZipOVOVVO: - Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P1.Output == Void, - P3.Output == Void, - P4.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - self.p5 = p5 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P0.Output, - P2.Output, - P5.Output - ) { - do { - let o0 = try p0.parse(&input) - try p1.parse(&input) - let o2 = try p2.parse(&input) - try p3.parse(&input) - try p4.parse(&input) - let o5 = try p5.parse(&input) - return (o0, o2, o5) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipOVOVVO: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P5: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P1.Output == Void, - P3.Output == Void, - P4.Output == Void - { - @inlinable public func print( - _ output: ( - P0.Output, - P2.Output, - P5.Output - ), - into input: inout P0.Input - ) rethrows { - try p5.print(output.2, into: &input) - try p4.print(into: &input) - try p3.print(into: &input) - try p2.print(output.1, into: &input) - try p1.print(into: &input) - try p0.print(output.0, into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 - ) -> ParserBuilder.ZipOVOVVO { - ParserBuilder.ZipOVOVVO(p0, p1, p2, p3, p4, p5) - } - } - - extension ParserBuilder { - public struct ZipOVOVVV: - Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P1.Output == Void, - P3.Output == Void, - P4.Output == Void, - P5.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - self.p5 = p5 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P0.Output, - P2.Output - ) { - do { - let o0 = try p0.parse(&input) - try p1.parse(&input) - let o2 = try p2.parse(&input) - try p3.parse(&input) - try p4.parse(&input) - try p5.parse(&input) - return (o0, o2) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipOVOVVV: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P5: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P1.Output == Void, - P3.Output == Void, - P4.Output == Void, - P5.Output == Void - { - @inlinable public func print( - _ output: ( - P0.Output, - P2.Output - ), - into input: inout P0.Input - ) rethrows { - try p5.print(into: &input) - try p4.print(into: &input) - try p3.print(into: &input) - try p2.print(output.1, into: &input) - try p1.print(into: &input) - try p0.print(output.0, into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 - ) -> ParserBuilder.ZipOVOVVV { - ParserBuilder.ZipOVOVVV(p0, p1, p2, p3, p4, p5) - } - } - - extension ParserBuilder { - public struct ZipOVVOOO: - Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P1.Output == Void, - P2.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - self.p5 = p5 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P0.Output, - P3.Output, - P4.Output, - P5.Output - ) { - do { - let o0 = try p0.parse(&input) - try p1.parse(&input) - try p2.parse(&input) - let o3 = try p3.parse(&input) - let o4 = try p4.parse(&input) - let o5 = try p5.parse(&input) - return (o0, o3, o4, o5) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipOVVOOO: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P5: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P1.Output == Void, - P2.Output == Void - { - @inlinable public func print( - _ output: ( - P0.Output, - P3.Output, - P4.Output, - P5.Output - ), - into input: inout P0.Input - ) rethrows { - try p5.print(output.3, into: &input) - try p4.print(output.2, into: &input) - try p3.print(output.1, into: &input) - try p2.print(into: &input) - try p1.print(into: &input) - try p0.print(output.0, into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 - ) -> ParserBuilder.ZipOVVOOO { - ParserBuilder.ZipOVVOOO(p0, p1, p2, p3, p4, p5) - } - } - - extension ParserBuilder { - public struct ZipOVVOOV: - Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P1.Output == Void, - P2.Output == Void, - P5.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - self.p5 = p5 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P0.Output, - P3.Output, - P4.Output - ) { - do { - let o0 = try p0.parse(&input) - try p1.parse(&input) - try p2.parse(&input) - let o3 = try p3.parse(&input) - let o4 = try p4.parse(&input) - try p5.parse(&input) - return (o0, o3, o4) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipOVVOOV: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P5: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P1.Output == Void, - P2.Output == Void, - P5.Output == Void - { - @inlinable public func print( - _ output: ( - P0.Output, - P3.Output, - P4.Output - ), - into input: inout P0.Input - ) rethrows { - try p5.print(into: &input) - try p4.print(output.2, into: &input) - try p3.print(output.1, into: &input) - try p2.print(into: &input) - try p1.print(into: &input) - try p0.print(output.0, into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 - ) -> ParserBuilder.ZipOVVOOV { - ParserBuilder.ZipOVVOOV(p0, p1, p2, p3, p4, p5) - } - } - - extension ParserBuilder { - public struct ZipOVVOVO: - Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P1.Output == Void, - P2.Output == Void, - P4.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - self.p5 = p5 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P0.Output, - P3.Output, - P5.Output - ) { - do { - let o0 = try p0.parse(&input) - try p1.parse(&input) - try p2.parse(&input) - let o3 = try p3.parse(&input) - try p4.parse(&input) - let o5 = try p5.parse(&input) - return (o0, o3, o5) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipOVVOVO: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P5: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P1.Output == Void, - P2.Output == Void, - P4.Output == Void - { - @inlinable public func print( - _ output: ( - P0.Output, - P3.Output, - P5.Output - ), - into input: inout P0.Input - ) rethrows { - try p5.print(output.2, into: &input) - try p4.print(into: &input) - try p3.print(output.1, into: &input) - try p2.print(into: &input) - try p1.print(into: &input) - try p0.print(output.0, into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 - ) -> ParserBuilder.ZipOVVOVO { - ParserBuilder.ZipOVVOVO(p0, p1, p2, p3, p4, p5) - } - } - - extension ParserBuilder { - public struct ZipOVVOVV: - Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P1.Output == Void, - P2.Output == Void, - P4.Output == Void, - P5.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - self.p5 = p5 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P0.Output, - P3.Output - ) { - do { - let o0 = try p0.parse(&input) - try p1.parse(&input) - try p2.parse(&input) - let o3 = try p3.parse(&input) - try p4.parse(&input) - try p5.parse(&input) - return (o0, o3) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipOVVOVV: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P5: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P1.Output == Void, - P2.Output == Void, - P4.Output == Void, - P5.Output == Void - { - @inlinable public func print( - _ output: ( - P0.Output, - P3.Output - ), - into input: inout P0.Input - ) rethrows { - try p5.print(into: &input) - try p4.print(into: &input) - try p3.print(output.1, into: &input) - try p2.print(into: &input) - try p1.print(into: &input) - try p0.print(output.0, into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 - ) -> ParserBuilder.ZipOVVOVV { - ParserBuilder.ZipOVVOVV(p0, p1, p2, p3, p4, p5) - } - } - - extension ParserBuilder { - public struct ZipOVVVOO: - Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P1.Output == Void, - P2.Output == Void, - P3.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - self.p5 = p5 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P0.Output, - P4.Output, - P5.Output - ) { - do { - let o0 = try p0.parse(&input) - try p1.parse(&input) - try p2.parse(&input) - try p3.parse(&input) - let o4 = try p4.parse(&input) - let o5 = try p5.parse(&input) - return (o0, o4, o5) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipOVVVOO: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P5: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P1.Output == Void, - P2.Output == Void, - P3.Output == Void - { - @inlinable public func print( - _ output: ( - P0.Output, - P4.Output, - P5.Output - ), - into input: inout P0.Input - ) rethrows { - try p5.print(output.2, into: &input) - try p4.print(output.1, into: &input) - try p3.print(into: &input) - try p2.print(into: &input) - try p1.print(into: &input) - try p0.print(output.0, into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 - ) -> ParserBuilder.ZipOVVVOO { - ParserBuilder.ZipOVVVOO(p0, p1, p2, p3, p4, p5) - } - } - - extension ParserBuilder { - public struct ZipOVVVOV: - Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P1.Output == Void, - P2.Output == Void, - P3.Output == Void, - P5.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - self.p5 = p5 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P0.Output, - P4.Output - ) { - do { - let o0 = try p0.parse(&input) - try p1.parse(&input) - try p2.parse(&input) - try p3.parse(&input) - let o4 = try p4.parse(&input) - try p5.parse(&input) - return (o0, o4) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipOVVVOV: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P5: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P1.Output == Void, - P2.Output == Void, - P3.Output == Void, - P5.Output == Void - { - @inlinable public func print( - _ output: ( - P0.Output, - P4.Output - ), - into input: inout P0.Input - ) rethrows { - try p5.print(into: &input) - try p4.print(output.1, into: &input) - try p3.print(into: &input) - try p2.print(into: &input) - try p1.print(into: &input) - try p0.print(output.0, into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 - ) -> ParserBuilder.ZipOVVVOV { - ParserBuilder.ZipOVVVOV(p0, p1, p2, p3, p4, p5) - } - } - - extension ParserBuilder { - public struct ZipOVVVVO: - Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P1.Output == Void, - P2.Output == Void, - P3.Output == Void, - P4.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - self.p5 = p5 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P0.Output, - P5.Output - ) { - do { - let o0 = try p0.parse(&input) - try p1.parse(&input) - try p2.parse(&input) - try p3.parse(&input) - try p4.parse(&input) - let o5 = try p5.parse(&input) - return (o0, o5) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipOVVVVO: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P5: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P1.Output == Void, - P2.Output == Void, - P3.Output == Void, - P4.Output == Void - { - @inlinable public func print( - _ output: ( - P0.Output, - P5.Output - ), - into input: inout P0.Input - ) rethrows { - try p5.print(output.1, into: &input) - try p4.print(into: &input) - try p3.print(into: &input) - try p2.print(into: &input) - try p1.print(into: &input) - try p0.print(output.0, into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 - ) -> ParserBuilder.ZipOVVVVO { - ParserBuilder.ZipOVVVVO(p0, p1, p2, p3, p4, p5) - } - } - - extension ParserBuilder { - public struct ZipOVVVVV: - Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P1.Output == Void, - P2.Output == Void, - P3.Output == Void, - P4.Output == Void, - P5.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - self.p5 = p5 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> P0.Output { - do { - let o0 = try p0.parse(&input) - try p1.parse(&input) - try p2.parse(&input) - try p3.parse(&input) - try p4.parse(&input) - try p5.parse(&input) - return o0 - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipOVVVVV: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P5: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P1.Output == Void, - P2.Output == Void, - P3.Output == Void, - P4.Output == Void, - P5.Output == Void - { - @inlinable public func print( - _ output: P0.Output, - into input: inout P0.Input - ) rethrows { - try p5.print(into: &input) - try p4.print(into: &input) - try p3.print(into: &input) - try p2.print(into: &input) - try p1.print(into: &input) - try p0.print(output, into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 - ) -> ParserBuilder.ZipOVVVVV { - ParserBuilder.ZipOVVVVV(p0, p1, p2, p3, p4, p5) - } - } - - extension ParserBuilder { - public struct ZipVOOOOO: - Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P0.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - self.p5 = p5 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P1.Output, - P2.Output, - P3.Output, - P4.Output, - P5.Output - ) { - do { - try p0.parse(&input) - let o1 = try p1.parse(&input) - let o2 = try p2.parse(&input) - let o3 = try p3.parse(&input) - let o4 = try p4.parse(&input) - let o5 = try p5.parse(&input) - return (o1, o2, o3, o4, o5) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipVOOOOO: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P5: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P0.Output == Void - { - @inlinable public func print( - _ output: ( - P1.Output, - P2.Output, - P3.Output, - P4.Output, - P5.Output - ), - into input: inout P0.Input - ) rethrows { - try p5.print(output.4, into: &input) - try p4.print(output.3, into: &input) - try p3.print(output.2, into: &input) - try p2.print(output.1, into: &input) - try p1.print(output.0, into: &input) - try p0.print(into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 - ) -> ParserBuilder.ZipVOOOOO { - ParserBuilder.ZipVOOOOO(p0, p1, p2, p3, p4, p5) - } - } - - extension ParserBuilder { - public struct ZipVOOOOV: - Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P0.Output == Void, - P5.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - self.p5 = p5 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P1.Output, - P2.Output, - P3.Output, - P4.Output - ) { - do { - try p0.parse(&input) - let o1 = try p1.parse(&input) - let o2 = try p2.parse(&input) - let o3 = try p3.parse(&input) - let o4 = try p4.parse(&input) - try p5.parse(&input) - return (o1, o2, o3, o4) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipVOOOOV: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P5: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P0.Output == Void, - P5.Output == Void - { - @inlinable public func print( - _ output: ( - P1.Output, - P2.Output, - P3.Output, - P4.Output - ), - into input: inout P0.Input - ) rethrows { - try p5.print(into: &input) - try p4.print(output.3, into: &input) - try p3.print(output.2, into: &input) - try p2.print(output.1, into: &input) - try p1.print(output.0, into: &input) - try p0.print(into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 - ) -> ParserBuilder.ZipVOOOOV { - ParserBuilder.ZipVOOOOV(p0, p1, p2, p3, p4, p5) - } - } - - extension ParserBuilder { - public struct ZipVOOOVO: - Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P0.Output == Void, - P4.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - self.p5 = p5 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P1.Output, - P2.Output, - P3.Output, - P5.Output - ) { - do { - try p0.parse(&input) - let o1 = try p1.parse(&input) - let o2 = try p2.parse(&input) - let o3 = try p3.parse(&input) - try p4.parse(&input) - let o5 = try p5.parse(&input) - return (o1, o2, o3, o5) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipVOOOVO: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P5: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P0.Output == Void, - P4.Output == Void - { - @inlinable public func print( - _ output: ( - P1.Output, - P2.Output, - P3.Output, - P5.Output - ), - into input: inout P0.Input - ) rethrows { - try p5.print(output.3, into: &input) - try p4.print(into: &input) - try p3.print(output.2, into: &input) - try p2.print(output.1, into: &input) - try p1.print(output.0, into: &input) - try p0.print(into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 - ) -> ParserBuilder.ZipVOOOVO { - ParserBuilder.ZipVOOOVO(p0, p1, p2, p3, p4, p5) - } - } - - extension ParserBuilder { - public struct ZipVOOOVV: - Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P0.Output == Void, - P4.Output == Void, - P5.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - self.p5 = p5 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P1.Output, - P2.Output, - P3.Output - ) { - do { - try p0.parse(&input) - let o1 = try p1.parse(&input) - let o2 = try p2.parse(&input) - let o3 = try p3.parse(&input) - try p4.parse(&input) - try p5.parse(&input) - return (o1, o2, o3) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipVOOOVV: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P5: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P0.Output == Void, - P4.Output == Void, - P5.Output == Void - { - @inlinable public func print( - _ output: ( - P1.Output, - P2.Output, - P3.Output - ), - into input: inout P0.Input - ) rethrows { - try p5.print(into: &input) - try p4.print(into: &input) - try p3.print(output.2, into: &input) - try p2.print(output.1, into: &input) - try p1.print(output.0, into: &input) - try p0.print(into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 - ) -> ParserBuilder.ZipVOOOVV { - ParserBuilder.ZipVOOOVV(p0, p1, p2, p3, p4, p5) - } - } - - extension ParserBuilder { - public struct ZipVOOVOO: - Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P0.Output == Void, - P3.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - self.p5 = p5 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P1.Output, - P2.Output, - P4.Output, - P5.Output - ) { - do { - try p0.parse(&input) - let o1 = try p1.parse(&input) - let o2 = try p2.parse(&input) - try p3.parse(&input) - let o4 = try p4.parse(&input) - let o5 = try p5.parse(&input) - return (o1, o2, o4, o5) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipVOOVOO: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P5: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P0.Output == Void, - P3.Output == Void - { - @inlinable public func print( - _ output: ( - P1.Output, - P2.Output, - P4.Output, - P5.Output - ), - into input: inout P0.Input - ) rethrows { - try p5.print(output.3, into: &input) - try p4.print(output.2, into: &input) - try p3.print(into: &input) - try p2.print(output.1, into: &input) - try p1.print(output.0, into: &input) - try p0.print(into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 - ) -> ParserBuilder.ZipVOOVOO { - ParserBuilder.ZipVOOVOO(p0, p1, p2, p3, p4, p5) - } - } - - extension ParserBuilder { - public struct ZipVOOVOV: - Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P0.Output == Void, - P3.Output == Void, - P5.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - self.p5 = p5 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P1.Output, - P2.Output, - P4.Output - ) { - do { - try p0.parse(&input) - let o1 = try p1.parse(&input) - let o2 = try p2.parse(&input) - try p3.parse(&input) - let o4 = try p4.parse(&input) - try p5.parse(&input) - return (o1, o2, o4) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipVOOVOV: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P5: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P0.Output == Void, - P3.Output == Void, - P5.Output == Void - { - @inlinable public func print( - _ output: ( - P1.Output, - P2.Output, - P4.Output - ), - into input: inout P0.Input - ) rethrows { - try p5.print(into: &input) - try p4.print(output.2, into: &input) - try p3.print(into: &input) - try p2.print(output.1, into: &input) - try p1.print(output.0, into: &input) - try p0.print(into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 - ) -> ParserBuilder.ZipVOOVOV { - ParserBuilder.ZipVOOVOV(p0, p1, p2, p3, p4, p5) - } - } - - extension ParserBuilder { - public struct ZipVOOVVO: - Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P0.Output == Void, - P3.Output == Void, - P4.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - self.p5 = p5 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P1.Output, - P2.Output, - P5.Output - ) { - do { - try p0.parse(&input) - let o1 = try p1.parse(&input) - let o2 = try p2.parse(&input) - try p3.parse(&input) - try p4.parse(&input) - let o5 = try p5.parse(&input) - return (o1, o2, o5) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipVOOVVO: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P5: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P0.Output == Void, - P3.Output == Void, - P4.Output == Void - { - @inlinable public func print( - _ output: ( - P1.Output, - P2.Output, - P5.Output - ), - into input: inout P0.Input - ) rethrows { - try p5.print(output.2, into: &input) - try p4.print(into: &input) - try p3.print(into: &input) - try p2.print(output.1, into: &input) - try p1.print(output.0, into: &input) - try p0.print(into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 - ) -> ParserBuilder.ZipVOOVVO { - ParserBuilder.ZipVOOVVO(p0, p1, p2, p3, p4, p5) - } - } - - extension ParserBuilder { - public struct ZipVOOVVV: - Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P0.Output == Void, - P3.Output == Void, - P4.Output == Void, - P5.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - self.p5 = p5 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P1.Output, - P2.Output - ) { - do { - try p0.parse(&input) - let o1 = try p1.parse(&input) - let o2 = try p2.parse(&input) - try p3.parse(&input) - try p4.parse(&input) - try p5.parse(&input) - return (o1, o2) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipVOOVVV: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P5: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P0.Output == Void, - P3.Output == Void, - P4.Output == Void, - P5.Output == Void - { - @inlinable public func print( - _ output: ( - P1.Output, - P2.Output - ), - into input: inout P0.Input - ) rethrows { - try p5.print(into: &input) - try p4.print(into: &input) - try p3.print(into: &input) - try p2.print(output.1, into: &input) - try p1.print(output.0, into: &input) - try p0.print(into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 - ) -> ParserBuilder.ZipVOOVVV { - ParserBuilder.ZipVOOVVV(p0, p1, p2, p3, p4, p5) - } - } - - extension ParserBuilder { - public struct ZipVOVOOO: - Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P0.Output == Void, - P2.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - self.p5 = p5 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P1.Output, - P3.Output, - P4.Output, - P5.Output - ) { - do { - try p0.parse(&input) - let o1 = try p1.parse(&input) - try p2.parse(&input) - let o3 = try p3.parse(&input) - let o4 = try p4.parse(&input) - let o5 = try p5.parse(&input) - return (o1, o3, o4, o5) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipVOVOOO: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P5: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P0.Output == Void, - P2.Output == Void - { - @inlinable public func print( - _ output: ( - P1.Output, - P3.Output, - P4.Output, - P5.Output - ), - into input: inout P0.Input - ) rethrows { - try p5.print(output.3, into: &input) - try p4.print(output.2, into: &input) - try p3.print(output.1, into: &input) - try p2.print(into: &input) - try p1.print(output.0, into: &input) - try p0.print(into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 - ) -> ParserBuilder.ZipVOVOOO { - ParserBuilder.ZipVOVOOO(p0, p1, p2, p3, p4, p5) - } - } - - extension ParserBuilder { - public struct ZipVOVOOV: - Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P0.Output == Void, - P2.Output == Void, - P5.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - self.p5 = p5 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P1.Output, - P3.Output, - P4.Output - ) { - do { - try p0.parse(&input) - let o1 = try p1.parse(&input) - try p2.parse(&input) - let o3 = try p3.parse(&input) - let o4 = try p4.parse(&input) - try p5.parse(&input) - return (o1, o3, o4) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipVOVOOV: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P5: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P0.Output == Void, - P2.Output == Void, - P5.Output == Void - { - @inlinable public func print( - _ output: ( - P1.Output, - P3.Output, - P4.Output - ), - into input: inout P0.Input - ) rethrows { - try p5.print(into: &input) - try p4.print(output.2, into: &input) - try p3.print(output.1, into: &input) - try p2.print(into: &input) - try p1.print(output.0, into: &input) - try p0.print(into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 - ) -> ParserBuilder.ZipVOVOOV { - ParserBuilder.ZipVOVOOV(p0, p1, p2, p3, p4, p5) - } - } - - extension ParserBuilder { - public struct ZipVOVOVO: - Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P0.Output == Void, - P2.Output == Void, - P4.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - self.p5 = p5 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P1.Output, - P3.Output, - P5.Output - ) { - do { - try p0.parse(&input) - let o1 = try p1.parse(&input) - try p2.parse(&input) - let o3 = try p3.parse(&input) - try p4.parse(&input) - let o5 = try p5.parse(&input) - return (o1, o3, o5) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipVOVOVO: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P5: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P0.Output == Void, - P2.Output == Void, - P4.Output == Void - { - @inlinable public func print( - _ output: ( - P1.Output, - P3.Output, - P5.Output - ), - into input: inout P0.Input - ) rethrows { - try p5.print(output.2, into: &input) - try p4.print(into: &input) - try p3.print(output.1, into: &input) - try p2.print(into: &input) - try p1.print(output.0, into: &input) - try p0.print(into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 - ) -> ParserBuilder.ZipVOVOVO { - ParserBuilder.ZipVOVOVO(p0, p1, p2, p3, p4, p5) - } - } - - extension ParserBuilder { - public struct ZipVOVOVV: - Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P0.Output == Void, - P2.Output == Void, - P4.Output == Void, - P5.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - self.p5 = p5 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P1.Output, - P3.Output - ) { - do { - try p0.parse(&input) - let o1 = try p1.parse(&input) - try p2.parse(&input) - let o3 = try p3.parse(&input) - try p4.parse(&input) - try p5.parse(&input) - return (o1, o3) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipVOVOVV: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P5: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P0.Output == Void, - P2.Output == Void, - P4.Output == Void, - P5.Output == Void - { - @inlinable public func print( - _ output: ( - P1.Output, - P3.Output - ), - into input: inout P0.Input - ) rethrows { - try p5.print(into: &input) - try p4.print(into: &input) - try p3.print(output.1, into: &input) - try p2.print(into: &input) - try p1.print(output.0, into: &input) - try p0.print(into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 - ) -> ParserBuilder.ZipVOVOVV { - ParserBuilder.ZipVOVOVV(p0, p1, p2, p3, p4, p5) - } - } - - extension ParserBuilder { - public struct ZipVOVVOO: - Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P0.Output == Void, - P2.Output == Void, - P3.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - self.p5 = p5 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P1.Output, - P4.Output, - P5.Output - ) { - do { - try p0.parse(&input) - let o1 = try p1.parse(&input) - try p2.parse(&input) - try p3.parse(&input) - let o4 = try p4.parse(&input) - let o5 = try p5.parse(&input) - return (o1, o4, o5) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipVOVVOO: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P5: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P0.Output == Void, - P2.Output == Void, - P3.Output == Void - { - @inlinable public func print( - _ output: ( - P1.Output, - P4.Output, - P5.Output - ), - into input: inout P0.Input - ) rethrows { - try p5.print(output.2, into: &input) - try p4.print(output.1, into: &input) - try p3.print(into: &input) - try p2.print(into: &input) - try p1.print(output.0, into: &input) - try p0.print(into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 - ) -> ParserBuilder.ZipVOVVOO { - ParserBuilder.ZipVOVVOO(p0, p1, p2, p3, p4, p5) - } - } - - extension ParserBuilder { - public struct ZipVOVVOV: - Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P0.Output == Void, - P2.Output == Void, - P3.Output == Void, - P5.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - self.p5 = p5 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P1.Output, - P4.Output - ) { - do { - try p0.parse(&input) - let o1 = try p1.parse(&input) - try p2.parse(&input) - try p3.parse(&input) - let o4 = try p4.parse(&input) - try p5.parse(&input) - return (o1, o4) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipVOVVOV: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P5: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P0.Output == Void, - P2.Output == Void, - P3.Output == Void, - P5.Output == Void - { - @inlinable public func print( - _ output: ( - P1.Output, - P4.Output - ), - into input: inout P0.Input - ) rethrows { - try p5.print(into: &input) - try p4.print(output.1, into: &input) - try p3.print(into: &input) - try p2.print(into: &input) - try p1.print(output.0, into: &input) - try p0.print(into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 - ) -> ParserBuilder.ZipVOVVOV { - ParserBuilder.ZipVOVVOV(p0, p1, p2, p3, p4, p5) - } - } - - extension ParserBuilder { - public struct ZipVOVVVO: - Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P0.Output == Void, - P2.Output == Void, - P3.Output == Void, - P4.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - self.p5 = p5 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P1.Output, - P5.Output - ) { - do { - try p0.parse(&input) - let o1 = try p1.parse(&input) - try p2.parse(&input) - try p3.parse(&input) - try p4.parse(&input) - let o5 = try p5.parse(&input) - return (o1, o5) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipVOVVVO: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P5: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P0.Output == Void, - P2.Output == Void, - P3.Output == Void, - P4.Output == Void - { - @inlinable public func print( - _ output: ( - P1.Output, - P5.Output - ), - into input: inout P0.Input - ) rethrows { - try p5.print(output.1, into: &input) - try p4.print(into: &input) - try p3.print(into: &input) - try p2.print(into: &input) - try p1.print(output.0, into: &input) - try p0.print(into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 - ) -> ParserBuilder.ZipVOVVVO { - ParserBuilder.ZipVOVVVO(p0, p1, p2, p3, p4, p5) - } - } - - extension ParserBuilder { - public struct ZipVOVVVV: - Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P0.Output == Void, - P2.Output == Void, - P3.Output == Void, - P4.Output == Void, - P5.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - self.p5 = p5 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> P1.Output { - do { - try p0.parse(&input) - let o1 = try p1.parse(&input) - try p2.parse(&input) - try p3.parse(&input) - try p4.parse(&input) - try p5.parse(&input) - return o1 - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipVOVVVV: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P5: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P0.Output == Void, - P2.Output == Void, - P3.Output == Void, - P4.Output == Void, - P5.Output == Void - { - @inlinable public func print( - _ output: P1.Output, - into input: inout P0.Input - ) rethrows { - try p5.print(into: &input) - try p4.print(into: &input) - try p3.print(into: &input) - try p2.print(into: &input) - try p1.print(output, into: &input) - try p0.print(into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 - ) -> ParserBuilder.ZipVOVVVV { - ParserBuilder.ZipVOVVVV(p0, p1, p2, p3, p4, p5) - } - } - - extension ParserBuilder { - public struct ZipVVOOOO: - Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P0.Output == Void, - P1.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - self.p5 = p5 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P2.Output, - P3.Output, - P4.Output, - P5.Output - ) { - do { - try p0.parse(&input) - try p1.parse(&input) - let o2 = try p2.parse(&input) - let o3 = try p3.parse(&input) - let o4 = try p4.parse(&input) - let o5 = try p5.parse(&input) - return (o2, o3, o4, o5) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipVVOOOO: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P5: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P0.Output == Void, - P1.Output == Void - { - @inlinable public func print( - _ output: ( - P2.Output, - P3.Output, - P4.Output, - P5.Output - ), - into input: inout P0.Input - ) rethrows { - try p5.print(output.3, into: &input) - try p4.print(output.2, into: &input) - try p3.print(output.1, into: &input) - try p2.print(output.0, into: &input) - try p1.print(into: &input) - try p0.print(into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 - ) -> ParserBuilder.ZipVVOOOO { - ParserBuilder.ZipVVOOOO(p0, p1, p2, p3, p4, p5) - } - } - - extension ParserBuilder { - public struct ZipVVOOOV: - Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P0.Output == Void, - P1.Output == Void, - P5.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - self.p5 = p5 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P2.Output, - P3.Output, - P4.Output - ) { - do { - try p0.parse(&input) - try p1.parse(&input) - let o2 = try p2.parse(&input) - let o3 = try p3.parse(&input) - let o4 = try p4.parse(&input) - try p5.parse(&input) - return (o2, o3, o4) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipVVOOOV: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P5: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P0.Output == Void, - P1.Output == Void, - P5.Output == Void - { - @inlinable public func print( - _ output: ( - P2.Output, - P3.Output, - P4.Output - ), - into input: inout P0.Input - ) rethrows { - try p5.print(into: &input) - try p4.print(output.2, into: &input) - try p3.print(output.1, into: &input) - try p2.print(output.0, into: &input) - try p1.print(into: &input) - try p0.print(into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 - ) -> ParserBuilder.ZipVVOOOV { - ParserBuilder.ZipVVOOOV(p0, p1, p2, p3, p4, p5) - } - } - - extension ParserBuilder { - public struct ZipVVOOVO: - Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P0.Output == Void, - P1.Output == Void, - P4.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - self.p5 = p5 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P2.Output, - P3.Output, - P5.Output - ) { - do { - try p0.parse(&input) - try p1.parse(&input) - let o2 = try p2.parse(&input) - let o3 = try p3.parse(&input) - try p4.parse(&input) - let o5 = try p5.parse(&input) - return (o2, o3, o5) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipVVOOVO: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P5: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P0.Output == Void, - P1.Output == Void, - P4.Output == Void - { - @inlinable public func print( - _ output: ( - P2.Output, - P3.Output, - P5.Output - ), - into input: inout P0.Input - ) rethrows { - try p5.print(output.2, into: &input) - try p4.print(into: &input) - try p3.print(output.1, into: &input) - try p2.print(output.0, into: &input) - try p1.print(into: &input) - try p0.print(into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 - ) -> ParserBuilder.ZipVVOOVO { - ParserBuilder.ZipVVOOVO(p0, p1, p2, p3, p4, p5) - } - } - - extension ParserBuilder { - public struct ZipVVOOVV: - Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P0.Output == Void, - P1.Output == Void, - P4.Output == Void, - P5.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - self.p5 = p5 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P2.Output, - P3.Output - ) { - do { - try p0.parse(&input) - try p1.parse(&input) - let o2 = try p2.parse(&input) - let o3 = try p3.parse(&input) - try p4.parse(&input) - try p5.parse(&input) - return (o2, o3) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipVVOOVV: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P5: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P0.Output == Void, - P1.Output == Void, - P4.Output == Void, - P5.Output == Void - { - @inlinable public func print( - _ output: ( - P2.Output, - P3.Output - ), - into input: inout P0.Input - ) rethrows { - try p5.print(into: &input) - try p4.print(into: &input) - try p3.print(output.1, into: &input) - try p2.print(output.0, into: &input) - try p1.print(into: &input) - try p0.print(into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 - ) -> ParserBuilder.ZipVVOOVV { - ParserBuilder.ZipVVOOVV(p0, p1, p2, p3, p4, p5) - } - } - - extension ParserBuilder { - public struct ZipVVOVOO: - Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P0.Output == Void, - P1.Output == Void, - P3.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - self.p5 = p5 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P2.Output, - P4.Output, - P5.Output - ) { - do { - try p0.parse(&input) - try p1.parse(&input) - let o2 = try p2.parse(&input) - try p3.parse(&input) - let o4 = try p4.parse(&input) - let o5 = try p5.parse(&input) - return (o2, o4, o5) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipVVOVOO: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P5: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P0.Output == Void, - P1.Output == Void, - P3.Output == Void - { - @inlinable public func print( - _ output: ( - P2.Output, - P4.Output, - P5.Output - ), - into input: inout P0.Input - ) rethrows { - try p5.print(output.2, into: &input) - try p4.print(output.1, into: &input) - try p3.print(into: &input) - try p2.print(output.0, into: &input) - try p1.print(into: &input) - try p0.print(into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 - ) -> ParserBuilder.ZipVVOVOO { - ParserBuilder.ZipVVOVOO(p0, p1, p2, p3, p4, p5) - } - } - - extension ParserBuilder { - public struct ZipVVOVOV: - Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P0.Output == Void, - P1.Output == Void, - P3.Output == Void, - P5.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - self.p5 = p5 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P2.Output, - P4.Output - ) { - do { - try p0.parse(&input) - try p1.parse(&input) - let o2 = try p2.parse(&input) - try p3.parse(&input) - let o4 = try p4.parse(&input) - try p5.parse(&input) - return (o2, o4) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipVVOVOV: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P5: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P0.Output == Void, - P1.Output == Void, - P3.Output == Void, - P5.Output == Void - { - @inlinable public func print( - _ output: ( - P2.Output, - P4.Output - ), - into input: inout P0.Input - ) rethrows { - try p5.print(into: &input) - try p4.print(output.1, into: &input) - try p3.print(into: &input) - try p2.print(output.0, into: &input) - try p1.print(into: &input) - try p0.print(into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 - ) -> ParserBuilder.ZipVVOVOV { - ParserBuilder.ZipVVOVOV(p0, p1, p2, p3, p4, p5) - } - } - - extension ParserBuilder { - public struct ZipVVOVVO: - Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P0.Output == Void, - P1.Output == Void, - P3.Output == Void, - P4.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - self.p5 = p5 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P2.Output, - P5.Output - ) { - do { - try p0.parse(&input) - try p1.parse(&input) - let o2 = try p2.parse(&input) - try p3.parse(&input) - try p4.parse(&input) - let o5 = try p5.parse(&input) - return (o2, o5) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipVVOVVO: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P5: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P0.Output == Void, - P1.Output == Void, - P3.Output == Void, - P4.Output == Void - { - @inlinable public func print( - _ output: ( - P2.Output, - P5.Output - ), - into input: inout P0.Input - ) rethrows { - try p5.print(output.1, into: &input) - try p4.print(into: &input) - try p3.print(into: &input) - try p2.print(output.0, into: &input) - try p1.print(into: &input) - try p0.print(into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 - ) -> ParserBuilder.ZipVVOVVO { - ParserBuilder.ZipVVOVVO(p0, p1, p2, p3, p4, p5) - } - } - - extension ParserBuilder { - public struct ZipVVOVVV: - Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P0.Output == Void, - P1.Output == Void, - P3.Output == Void, - P4.Output == Void, - P5.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - self.p5 = p5 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> P2.Output { - do { - try p0.parse(&input) - try p1.parse(&input) - let o2 = try p2.parse(&input) - try p3.parse(&input) - try p4.parse(&input) - try p5.parse(&input) - return o2 - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipVVOVVV: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P5: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P0.Output == Void, - P1.Output == Void, - P3.Output == Void, - P4.Output == Void, - P5.Output == Void - { - @inlinable public func print( - _ output: P2.Output, - into input: inout P0.Input - ) rethrows { - try p5.print(into: &input) - try p4.print(into: &input) - try p3.print(into: &input) - try p2.print(output, into: &input) - try p1.print(into: &input) - try p0.print(into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 - ) -> ParserBuilder.ZipVVOVVV { - ParserBuilder.ZipVVOVVV(p0, p1, p2, p3, p4, p5) - } - } - - extension ParserBuilder { - public struct ZipVVVOOO: - Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P0.Output == Void, - P1.Output == Void, - P2.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - self.p5 = p5 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P3.Output, - P4.Output, - P5.Output - ) { - do { - try p0.parse(&input) - try p1.parse(&input) - try p2.parse(&input) - let o3 = try p3.parse(&input) - let o4 = try p4.parse(&input) - let o5 = try p5.parse(&input) - return (o3, o4, o5) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipVVVOOO: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P5: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P0.Output == Void, - P1.Output == Void, - P2.Output == Void - { - @inlinable public func print( - _ output: ( - P3.Output, - P4.Output, - P5.Output - ), - into input: inout P0.Input - ) rethrows { - try p5.print(output.2, into: &input) - try p4.print(output.1, into: &input) - try p3.print(output.0, into: &input) - try p2.print(into: &input) - try p1.print(into: &input) - try p0.print(into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 - ) -> ParserBuilder.ZipVVVOOO { - ParserBuilder.ZipVVVOOO(p0, p1, p2, p3, p4, p5) - } - } - - extension ParserBuilder { - public struct ZipVVVOOV: - Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P0.Output == Void, - P1.Output == Void, - P2.Output == Void, - P5.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - self.p5 = p5 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P3.Output, - P4.Output - ) { - do { - try p0.parse(&input) - try p1.parse(&input) - try p2.parse(&input) - let o3 = try p3.parse(&input) - let o4 = try p4.parse(&input) - try p5.parse(&input) - return (o3, o4) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipVVVOOV: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P5: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P0.Output == Void, - P1.Output == Void, - P2.Output == Void, - P5.Output == Void - { - @inlinable public func print( - _ output: ( - P3.Output, - P4.Output - ), - into input: inout P0.Input - ) rethrows { - try p5.print(into: &input) - try p4.print(output.1, into: &input) - try p3.print(output.0, into: &input) - try p2.print(into: &input) - try p1.print(into: &input) - try p0.print(into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 - ) -> ParserBuilder.ZipVVVOOV { - ParserBuilder.ZipVVVOOV(p0, p1, p2, p3, p4, p5) - } - } - - extension ParserBuilder { - public struct ZipVVVOVO: - Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P0.Output == Void, - P1.Output == Void, - P2.Output == Void, - P4.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - self.p5 = p5 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P3.Output, - P5.Output - ) { - do { - try p0.parse(&input) - try p1.parse(&input) - try p2.parse(&input) - let o3 = try p3.parse(&input) - try p4.parse(&input) - let o5 = try p5.parse(&input) - return (o3, o5) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipVVVOVO: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P5: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P0.Output == Void, - P1.Output == Void, - P2.Output == Void, - P4.Output == Void - { - @inlinable public func print( - _ output: ( - P3.Output, - P5.Output - ), - into input: inout P0.Input - ) rethrows { - try p5.print(output.1, into: &input) - try p4.print(into: &input) - try p3.print(output.0, into: &input) - try p2.print(into: &input) - try p1.print(into: &input) - try p0.print(into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 - ) -> ParserBuilder.ZipVVVOVO { - ParserBuilder.ZipVVVOVO(p0, p1, p2, p3, p4, p5) - } - } - - extension ParserBuilder { - public struct ZipVVVOVV: - Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P0.Output == Void, - P1.Output == Void, - P2.Output == Void, - P4.Output == Void, - P5.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - self.p5 = p5 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> P3.Output { - do { - try p0.parse(&input) - try p1.parse(&input) - try p2.parse(&input) - let o3 = try p3.parse(&input) - try p4.parse(&input) - try p5.parse(&input) - return o3 - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipVVVOVV: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P5: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P0.Output == Void, - P1.Output == Void, - P2.Output == Void, - P4.Output == Void, - P5.Output == Void - { - @inlinable public func print( - _ output: P3.Output, - into input: inout P0.Input - ) rethrows { - try p5.print(into: &input) - try p4.print(into: &input) - try p3.print(output, into: &input) - try p2.print(into: &input) - try p1.print(into: &input) - try p0.print(into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 - ) -> ParserBuilder.ZipVVVOVV { - ParserBuilder.ZipVVVOVV(p0, p1, p2, p3, p4, p5) - } - } - - extension ParserBuilder { - public struct ZipVVVVOO: - Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P0.Output == Void, - P1.Output == Void, - P2.Output == Void, - P3.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - self.p5 = p5 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> ( - P4.Output, - P5.Output - ) { - do { - try p0.parse(&input) - try p1.parse(&input) - try p2.parse(&input) - try p3.parse(&input) - let o4 = try p4.parse(&input) - let o5 = try p5.parse(&input) - return (o4, o5) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipVVVVOO: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P5: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P0.Output == Void, - P1.Output == Void, - P2.Output == Void, - P3.Output == Void - { - @inlinable public func print( - _ output: ( - P4.Output, - P5.Output - ), - into input: inout P0.Input - ) rethrows { - try p5.print(output.1, into: &input) - try p4.print(output.0, into: &input) - try p3.print(into: &input) - try p2.print(into: &input) - try p1.print(into: &input) - try p0.print(into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 - ) -> ParserBuilder.ZipVVVVOO { - ParserBuilder.ZipVVVVOO(p0, p1, p2, p3, p4, p5) - } - } - - extension ParserBuilder { - public struct ZipVVVVOV: - Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P0.Output == Void, - P1.Output == Void, - P2.Output == Void, - P3.Output == Void, - P5.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - self.p5 = p5 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> P4.Output { - do { - try p0.parse(&input) - try p1.parse(&input) - try p2.parse(&input) - try p3.parse(&input) - let o4 = try p4.parse(&input) - try p5.parse(&input) - return o4 - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipVVVVOV: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P5: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P0.Output == Void, - P1.Output == Void, - P2.Output == Void, - P3.Output == Void, - P5.Output == Void - { - @inlinable public func print( - _ output: P4.Output, - into input: inout P0.Input - ) rethrows { - try p5.print(into: &input) - try p4.print(output, into: &input) - try p3.print(into: &input) - try p2.print(into: &input) - try p1.print(into: &input) - try p0.print(into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 - ) -> ParserBuilder.ZipVVVVOV { - ParserBuilder.ZipVVVVOV(p0, p1, p2, p3, p4, p5) - } - } - - extension ParserBuilder { - public struct ZipVVVVVO: - Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P0.Output == Void, - P1.Output == Void, - P2.Output == Void, - P3.Output == Void, - P4.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - self.p5 = p5 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> P5.Output { - do { - try p0.parse(&input) - try p1.parse(&input) - try p2.parse(&input) - try p3.parse(&input) - try p4.parse(&input) - let o5 = try p5.parse(&input) - return o5 - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipVVVVVO: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P5: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P0.Output == Void, - P1.Output == Void, - P2.Output == Void, - P3.Output == Void, - P4.Output == Void - { - @inlinable public func print( - _ output: P5.Output, - into input: inout P0.Input - ) rethrows { - try p5.print(output, into: &input) - try p4.print(into: &input) - try p3.print(into: &input) - try p2.print(into: &input) - try p1.print(into: &input) - try p0.print(into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 - ) -> ParserBuilder.ZipVVVVVO { - ParserBuilder.ZipVVVVVO(p0, p1, p2, p3, p4, p5) - } - } - - extension ParserBuilder { - public struct ZipVVVVVV: - Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P0.Output == Void, - P1.Output == Void, - P2.Output == Void, - P3.Output == Void, - P4.Output == Void, - P5.Output == Void - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - self.p5 = p5 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows { - do { - try p0.parse(&input) - try p1.parse(&input) - try p2.parse(&input) - try p3.parse(&input) - try p4.parse(&input) - try p5.parse(&input) - } catch { throw ParsingError.wrap(error, at: input) } - } - } - } - - extension ParserBuilder.ZipVVVVVV: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P5: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P0.Output == Void, - P1.Output == Void, - P2.Output == Void, - P3.Output == Void, - P4.Output == Void, - P5.Output == Void - { - @inlinable public func print( - _ output: Void, - into input: inout P0.Input - ) rethrows { - try p5.print(into: &input) - try p4.print(into: &input) - try p3.print(into: &input) - try p2.print(into: &input) - try p1.print(into: &input) - try p0.print(into: &input) - } - } - - extension ParserBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 - ) -> ParserBuilder.ZipVVVVVV { - ParserBuilder.ZipVVVVVV(p0, p1, p2, p3, p4, p5) - } - } - - extension OneOfBuilder { - public struct OneOf3: Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P0.Output == P1.Output, - P1.Output == P2.Output - { - public let p0: P0, p1: P1, p2: P2 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> P0.Output { - let original = input - do { return try self.p0.parse(&input) } catch let e0 { - do { - input = original - return try self.p1.parse(&input) - } catch let e1 { - do { - input = original - return try self.p2.parse(&input) - } catch let e2 { - throw ParsingError.manyFailed( - [e0, e1, e2], at: input - ) - } - } - } - } - } - } - - extension OneOfBuilder.OneOf3: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P0.Output == P1.Output, - P1.Output == P2.Output - { - @inlinable public func print(_ output: P0.Output, into input: inout P0.Input) rethrows { - let original = input - do { try self.p2.print(output, into: &input) } catch let e2 { - do { - input = original - try self.p1.print(output, into: &input) - } catch let e1 { - do { - input = original - try self.p0.print(output, into: &input) - } catch let e0 { - throw PrintingError.manyFailed( - [e2, e1, e0], at: input - ) - } - } - } - } - } - - extension OneOfBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2 - ) -> OneOfBuilder.OneOf3 { - OneOfBuilder.OneOf3(p0, p1, p2) - } - } - - extension OneOfBuilder { - public struct OneOf4: Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P0.Output == P1.Output, - P1.Output == P2.Output, - P2.Output == P3.Output - { - public let p0: P0, p1: P1, p2: P2, p3: P3 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> P0.Output { - let original = input - do { return try self.p0.parse(&input) } catch let e0 { - do { - input = original - return try self.p1.parse(&input) - } catch let e1 { - do { - input = original - return try self.p2.parse(&input) - } catch let e2 { - do { - input = original - return try self.p3.parse(&input) - } catch let e3 { - throw ParsingError.manyFailed( - [e0, e1, e2, e3], at: input - ) - } - } - } - } - } - } - } - - extension OneOfBuilder.OneOf4: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P0.Output == P1.Output, - P1.Output == P2.Output, - P2.Output == P3.Output - { - @inlinable public func print(_ output: P0.Output, into input: inout P0.Input) rethrows { - let original = input - do { try self.p3.print(output, into: &input) } catch let e3 { - do { - input = original - try self.p2.print(output, into: &input) - } catch let e2 { - do { - input = original - try self.p1.print(output, into: &input) - } catch let e1 { - do { - input = original - try self.p0.print(output, into: &input) - } catch let e0 { - throw PrintingError.manyFailed( - [e3, e2, e1, e0], at: input - ) - } - } - } - } - } - } - - extension OneOfBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3 - ) -> OneOfBuilder.OneOf4 { - OneOfBuilder.OneOf4(p0, p1, p2, p3) - } - } - - extension OneOfBuilder { - public struct OneOf5: Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P0.Output == P1.Output, - P1.Output == P2.Output, - P2.Output == P3.Output, - P3.Output == P4.Output - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> P0.Output { - let original = input - do { return try self.p0.parse(&input) } catch let e0 { - do { - input = original - return try self.p1.parse(&input) - } catch let e1 { - do { - input = original - return try self.p2.parse(&input) - } catch let e2 { - do { - input = original - return try self.p3.parse(&input) - } catch let e3 { - do { - input = original - return try self.p4.parse(&input) - } catch let e4 { - throw ParsingError.manyFailed( - [e0, e1, e2, e3, e4], at: input - ) - } - } - } - } - } - } - } - } - - extension OneOfBuilder.OneOf5: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P0.Output == P1.Output, - P1.Output == P2.Output, - P2.Output == P3.Output, - P3.Output == P4.Output - { - @inlinable public func print(_ output: P0.Output, into input: inout P0.Input) rethrows { - let original = input - do { try self.p4.print(output, into: &input) } catch let e4 { - do { - input = original - try self.p3.print(output, into: &input) - } catch let e3 { - do { - input = original - try self.p2.print(output, into: &input) - } catch let e2 { - do { - input = original - try self.p1.print(output, into: &input) - } catch let e1 { - do { - input = original - try self.p0.print(output, into: &input) - } catch let e0 { - throw PrintingError.manyFailed( - [e4, e3, e2, e1, e0], at: input - ) - } - } - } - } - } - } - } - - extension OneOfBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4 - ) -> OneOfBuilder.OneOf5 { - OneOfBuilder.OneOf5(p0, p1, p2, p3, p4) - } - } - - extension OneOfBuilder { - public struct OneOf6: - Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P0.Output == P1.Output, - P1.Output == P2.Output, - P2.Output == P3.Output, - P3.Output == P4.Output, - P4.Output == P5.Output - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - self.p5 = p5 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> P0.Output { - let original = input - do { return try self.p0.parse(&input) } catch let e0 { - do { - input = original - return try self.p1.parse(&input) - } catch let e1 { - do { - input = original - return try self.p2.parse(&input) - } catch let e2 { - do { - input = original - return try self.p3.parse(&input) - } catch let e3 { - do { - input = original - return try self.p4.parse(&input) - } catch let e4 { - do { - input = original - return try self.p5.parse(&input) - } catch let e5 { - throw ParsingError.manyFailed( - [e0, e1, e2, e3, e4, e5], at: input - ) - } - } - } - } - } - } - } - } - } - - extension OneOfBuilder.OneOf6: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P5: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P0.Output == P1.Output, - P1.Output == P2.Output, - P2.Output == P3.Output, - P3.Output == P4.Output, - P4.Output == P5.Output - { - @inlinable public func print(_ output: P0.Output, into input: inout P0.Input) rethrows { - let original = input - do { try self.p5.print(output, into: &input) } catch let e5 { - do { - input = original - try self.p4.print(output, into: &input) - } catch let e4 { - do { - input = original - try self.p3.print(output, into: &input) - } catch let e3 { - do { - input = original - try self.p2.print(output, into: &input) - } catch let e2 { - do { - input = original - try self.p1.print(output, into: &input) - } catch let e1 { - do { - input = original - try self.p0.print(output, into: &input) - } catch let e0 { - throw PrintingError.manyFailed( - [e5, e4, e3, e2, e1, e0], at: input - ) - } - } - } - } - } - } - } - } - - extension OneOfBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 - ) -> OneOfBuilder.OneOf6 { - OneOfBuilder.OneOf6(p0, p1, p2, p3, p4, p5) - } - } - - extension OneOfBuilder { - public struct OneOf7< - P0: Parser, P1: Parser, P2: Parser, P3: Parser, P4: Parser, P5: Parser, P6: Parser - >: Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P5.Input == P6.Input, - P0.Output == P1.Output, - P1.Output == P2.Output, - P2.Output == P3.Output, - P3.Output == P4.Output, - P4.Output == P5.Output, - P5.Output == P6.Output - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6 - - @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5, _ p6: P6) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - self.p5 = p5 - self.p6 = p6 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> P0.Output { - let original = input - do { return try self.p0.parse(&input) } catch let e0 { - do { - input = original - return try self.p1.parse(&input) - } catch let e1 { - do { - input = original - return try self.p2.parse(&input) - } catch let e2 { - do { - input = original - return try self.p3.parse(&input) - } catch let e3 { - do { - input = original - return try self.p4.parse(&input) - } catch let e4 { - do { - input = original - return try self.p5.parse(&input) - } catch let e5 { - do { - input = original - return try self.p6.parse(&input) - } catch let e6 { - throw ParsingError.manyFailed( - [e0, e1, e2, e3, e4, e5, e6], at: input - ) - } - } - } - } - } - } - } - } - } - } - - extension OneOfBuilder.OneOf7: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P5: ParserPrinter, - P6: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P5.Input == P6.Input, - P0.Output == P1.Output, - P1.Output == P2.Output, - P2.Output == P3.Output, - P3.Output == P4.Output, - P4.Output == P5.Output, - P5.Output == P6.Output - { - @inlinable public func print(_ output: P0.Output, into input: inout P0.Input) rethrows { - let original = input - do { try self.p6.print(output, into: &input) } catch let e6 { - do { - input = original - try self.p5.print(output, into: &input) - } catch let e5 { - do { - input = original - try self.p4.print(output, into: &input) - } catch let e4 { - do { - input = original - try self.p3.print(output, into: &input) - } catch let e3 { - do { - input = original - try self.p2.print(output, into: &input) - } catch let e2 { - do { - input = original - try self.p1.print(output, into: &input) - } catch let e1 { - do { - input = original - try self.p0.print(output, into: &input) - } catch let e0 { - throw PrintingError.manyFailed( - [e6, e5, e4, e3, e2, e1, e0], at: input - ) - } - } - } - } - } - } - } - } - } - - extension OneOfBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5, _ p6: P6 - ) -> OneOfBuilder.OneOf7 { - OneOfBuilder.OneOf7(p0, p1, p2, p3, p4, p5, p6) - } - } - - extension OneOfBuilder { - public struct OneOf8< - P0: Parser, P1: Parser, P2: Parser, P3: Parser, P4: Parser, P5: Parser, P6: Parser, P7: Parser - >: Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P5.Input == P6.Input, - P6.Input == P7.Input, - P0.Output == P1.Output, - P1.Output == P2.Output, - P2.Output == P3.Output, - P3.Output == P4.Output, - P4.Output == P5.Output, - P5.Output == P6.Output, - P6.Output == P7.Output - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7 - - @inlinable public init( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5, _ p6: P6, _ p7: P7 - ) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - self.p5 = p5 - self.p6 = p6 - self.p7 = p7 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> P0.Output { - let original = input - do { return try self.p0.parse(&input) } catch let e0 { - do { - input = original - return try self.p1.parse(&input) - } catch let e1 { - do { - input = original - return try self.p2.parse(&input) - } catch let e2 { - do { - input = original - return try self.p3.parse(&input) - } catch let e3 { - do { - input = original - return try self.p4.parse(&input) - } catch let e4 { - do { - input = original - return try self.p5.parse(&input) - } catch let e5 { - do { - input = original - return try self.p6.parse(&input) - } catch let e6 { - do { - input = original - return try self.p7.parse(&input) - } catch let e7 { - throw ParsingError.manyFailed( - [e0, e1, e2, e3, e4, e5, e6, e7], at: input - ) - } - } - } - } - } - } - } - } - } - } - } - - extension OneOfBuilder.OneOf8: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P5: ParserPrinter, - P6: ParserPrinter, - P7: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P5.Input == P6.Input, - P6.Input == P7.Input, - P0.Output == P1.Output, - P1.Output == P2.Output, - P2.Output == P3.Output, - P3.Output == P4.Output, - P4.Output == P5.Output, - P5.Output == P6.Output, - P6.Output == P7.Output - { - @inlinable public func print(_ output: P0.Output, into input: inout P0.Input) rethrows { - let original = input - do { try self.p7.print(output, into: &input) } catch let e7 { - do { - input = original - try self.p6.print(output, into: &input) - } catch let e6 { - do { - input = original - try self.p5.print(output, into: &input) - } catch let e5 { - do { - input = original - try self.p4.print(output, into: &input) - } catch let e4 { - do { - input = original - try self.p3.print(output, into: &input) - } catch let e3 { - do { - input = original - try self.p2.print(output, into: &input) - } catch let e2 { - do { - input = original - try self.p1.print(output, into: &input) - } catch let e1 { - do { - input = original - try self.p0.print(output, into: &input) - } catch let e0 { - throw PrintingError.manyFailed( - [e7, e6, e5, e4, e3, e2, e1, e0], at: input - ) - } - } - } - } - } - } - } - } - } - } - - extension OneOfBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5, _ p6: P6, _ p7: P7 - ) -> OneOfBuilder.OneOf8 { - OneOfBuilder.OneOf8(p0, p1, p2, p3, p4, p5, p6, p7) - } - } - - extension OneOfBuilder { - public struct OneOf9< - P0: Parser, P1: Parser, P2: Parser, P3: Parser, P4: Parser, P5: Parser, P6: Parser, - P7: Parser, P8: Parser - >: Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P5.Input == P6.Input, - P6.Input == P7.Input, - P7.Input == P8.Input, - P0.Output == P1.Output, - P1.Output == P2.Output, - P2.Output == P3.Output, - P3.Output == P4.Output, - P4.Output == P5.Output, - P5.Output == P6.Output, - P6.Output == P7.Output, - P7.Output == P8.Output - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8 - - @inlinable public init( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5, _ p6: P6, _ p7: P7, _ p8: P8 - ) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - self.p5 = p5 - self.p6 = p6 - self.p7 = p7 - self.p8 = p8 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> P0.Output { - let original = input - do { return try self.p0.parse(&input) } catch let e0 { - do { - input = original - return try self.p1.parse(&input) - } catch let e1 { - do { - input = original - return try self.p2.parse(&input) - } catch let e2 { - do { - input = original - return try self.p3.parse(&input) - } catch let e3 { - do { - input = original - return try self.p4.parse(&input) - } catch let e4 { - do { - input = original - return try self.p5.parse(&input) - } catch let e5 { - do { - input = original - return try self.p6.parse(&input) - } catch let e6 { - do { - input = original - return try self.p7.parse(&input) - } catch let e7 { - do { - input = original - return try self.p8.parse(&input) - } catch let e8 { - throw ParsingError.manyFailed( - [e0, e1, e2, e3, e4, e5, e6, e7, e8], at: input - ) - } - } - } - } - } - } - } - } - } - } - } - } - - extension OneOfBuilder.OneOf9: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P5: ParserPrinter, - P6: ParserPrinter, - P7: ParserPrinter, - P8: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P5.Input == P6.Input, - P6.Input == P7.Input, - P7.Input == P8.Input, - P0.Output == P1.Output, - P1.Output == P2.Output, - P2.Output == P3.Output, - P3.Output == P4.Output, - P4.Output == P5.Output, - P5.Output == P6.Output, - P6.Output == P7.Output, - P7.Output == P8.Output - { - @inlinable public func print(_ output: P0.Output, into input: inout P0.Input) rethrows { - let original = input - do { try self.p8.print(output, into: &input) } catch let e8 { - do { - input = original - try self.p7.print(output, into: &input) - } catch let e7 { - do { - input = original - try self.p6.print(output, into: &input) - } catch let e6 { - do { - input = original - try self.p5.print(output, into: &input) - } catch let e5 { - do { - input = original - try self.p4.print(output, into: &input) - } catch let e4 { - do { - input = original - try self.p3.print(output, into: &input) - } catch let e3 { - do { - input = original - try self.p2.print(output, into: &input) - } catch let e2 { - do { - input = original - try self.p1.print(output, into: &input) - } catch let e1 { - do { - input = original - try self.p0.print(output, into: &input) - } catch let e0 { - throw PrintingError.manyFailed( - [e8, e7, e6, e5, e4, e3, e2, e1, e0], at: input - ) - } - } - } - } - } - } - } - } - } - } - } - - extension OneOfBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5, _ p6: P6, _ p7: P7, _ p8: P8 - ) -> OneOfBuilder.OneOf9 { - OneOfBuilder.OneOf9(p0, p1, p2, p3, p4, p5, p6, p7, p8) - } - } - - extension OneOfBuilder { - public struct OneOf10< - P0: Parser, P1: Parser, P2: Parser, P3: Parser, P4: Parser, P5: Parser, P6: Parser, - P7: Parser, P8: Parser, P9: Parser - >: Parser - where - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P5.Input == P6.Input, - P6.Input == P7.Input, - P7.Input == P8.Input, - P8.Input == P9.Input, - P0.Output == P1.Output, - P1.Output == P2.Output, - P2.Output == P3.Output, - P3.Output == P4.Output, - P4.Output == P5.Output, - P5.Output == P6.Output, - P6.Output == P7.Output, - P7.Output == P8.Output, - P8.Output == P9.Output - { - public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9 - - @inlinable public init( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5, _ p6: P6, _ p7: P7, _ p8: P8, - _ p9: P9 - ) { - self.p0 = p0 - self.p1 = p1 - self.p2 = p2 - self.p3 = p3 - self.p4 = p4 - self.p5 = p5 - self.p6 = p6 - self.p7 = p7 - self.p8 = p8 - self.p9 = p9 - } - - @inlinable public func parse(_ input: inout P0.Input) rethrows -> P0.Output { - let original = input - do { return try self.p0.parse(&input) } catch let e0 { - do { - input = original - return try self.p1.parse(&input) - } catch let e1 { - do { - input = original - return try self.p2.parse(&input) - } catch let e2 { - do { - input = original - return try self.p3.parse(&input) - } catch let e3 { - do { - input = original - return try self.p4.parse(&input) - } catch let e4 { - do { - input = original - return try self.p5.parse(&input) - } catch let e5 { - do { - input = original - return try self.p6.parse(&input) - } catch let e6 { - do { - input = original - return try self.p7.parse(&input) - } catch let e7 { - do { - input = original - return try self.p8.parse(&input) - } catch let e8 { - do { - input = original - return try self.p9.parse(&input) - } catch let e9 { - throw ParsingError.manyFailed( - [e0, e1, e2, e3, e4, e5, e6, e7, e8, e9], at: input - ) - } - } - } - } - } - } - } - } - } - } - } - } - } - - extension OneOfBuilder.OneOf10: ParserPrinter - where - P0: ParserPrinter, - P1: ParserPrinter, - P2: ParserPrinter, - P3: ParserPrinter, - P4: ParserPrinter, - P5: ParserPrinter, - P6: ParserPrinter, - P7: ParserPrinter, - P8: ParserPrinter, - P9: ParserPrinter, - P0.Input == P1.Input, - P1.Input == P2.Input, - P2.Input == P3.Input, - P3.Input == P4.Input, - P4.Input == P5.Input, - P5.Input == P6.Input, - P6.Input == P7.Input, - P7.Input == P8.Input, - P8.Input == P9.Input, - P0.Output == P1.Output, - P1.Output == P2.Output, - P2.Output == P3.Output, - P3.Output == P4.Output, - P4.Output == P5.Output, - P5.Output == P6.Output, - P6.Output == P7.Output, - P7.Output == P8.Output, - P8.Output == P9.Output - { - @inlinable public func print(_ output: P0.Output, into input: inout P0.Input) rethrows { - let original = input - do { try self.p9.print(output, into: &input) } catch let e9 { - do { - input = original - try self.p8.print(output, into: &input) - } catch let e8 { - do { - input = original - try self.p7.print(output, into: &input) - } catch let e7 { - do { - input = original - try self.p6.print(output, into: &input) - } catch let e6 { - do { - input = original - try self.p5.print(output, into: &input) - } catch let e5 { - do { - input = original - try self.p4.print(output, into: &input) - } catch let e4 { - do { - input = original - try self.p3.print(output, into: &input) - } catch let e3 { - do { - input = original - try self.p2.print(output, into: &input) - } catch let e2 { - do { - input = original - try self.p1.print(output, into: &input) - } catch let e1 { - do { - input = original - try self.p0.print(output, into: &input) - } catch let e0 { - throw PrintingError.manyFailed( - [e9, e8, e7, e6, e5, e4, e3, e2, e1, e0], at: input - ) - } - } - } - } - } - } - } - } - } - } - } - } - - extension OneOfBuilder { - @inlinable public static func buildBlock( - _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5, _ p6: P6, _ p7: P7, _ p8: P8, - _ p9: P9 - ) -> OneOfBuilder.OneOf10 { - OneOfBuilder.OneOf10(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9) - } - } - -#endif - -// END AUTO-GENERATED CONTENT diff --git a/Sources/Parsing/Conversion.swift b/Sources/Parsing/Conversion.swift index a8f5929279..f1b0acae84 100644 --- a/Sources/Parsing/Conversion.swift +++ b/Sources/Parsing/Conversion.swift @@ -1,37 +1,28 @@ -#if swift(>=5.7) - /// Declares a type that can transform an `Input` value into an `Output` value *and* transform an - /// `Output` value back into an `Input` value. - /// - /// Useful in transforming the output of a parser-printer into some new type while preserving - /// printability via ``Parser/map(_:)-18m9d``. - @rethrows public protocol Conversion { - // The type of values this conversion converts from. - associatedtype Input +/// Declares a type that can transform an `Input` value into an `Output` value *and* transform an +/// `Output` value back into an `Input` value. +/// +/// Useful in transforming the output of a parser-printer into some new type while preserving +/// printability via ``Parser/map(_:)-18m9d``. +@rethrows public protocol Conversion { + // The type of values this conversion converts from. + associatedtype Input - // The type of values this conversion converts to. - associatedtype Output + // The type of values this conversion converts to. + associatedtype Output - /// Attempts to transform an input into an output. - /// - /// See ``Conversion/apply(_:)`` for the reverse process. - /// - /// - Parameter input: An input value. - /// - Returns: A transformed output value. - func apply(_ input: Input) throws -> Output + /// Attempts to transform an input into an output. + /// + /// See ``Conversion/apply(_:)`` for the reverse process. + /// + /// - Parameter input: An input value. + /// - Returns: A transformed output value. + func apply(_ input: Input) throws -> Output - /// Attempts to transform an output back into an input. - /// - /// The reverse process of ``Conversion/apply(_:)``. - /// - /// - Parameter output: An output value. - /// - Returns: An "un"-transformed input value. - func unapply(_ output: Output) throws -> Input - } -#else - @rethrows public protocol Conversion { - associatedtype Input - associatedtype Output - func apply(_ input: Input) throws -> Output - func unapply(_ output: Output) throws -> Input - } -#endif + /// Attempts to transform an output back into an input. + /// + /// The reverse process of ``Conversion/apply(_:)``. + /// + /// - Parameter output: An output value. + /// - Returns: An "un"-transformed input value. + func unapply(_ output: Output) throws -> Input +} diff --git a/Sources/Parsing/Documentation.docc/Articles/ErrorMessages.md b/Sources/Parsing/Documentation.docc/Articles/ErrorMessages.md index f358c1087b..8fccf876ba 100644 --- a/Sources/Parsing/Documentation.docc/Articles/ErrorMessages.md +++ b/Sources/Parsing/Documentation.docc/Articles/ErrorMessages.md @@ -12,8 +12,8 @@ For example, the following `UInt8` parser fails to parse a string that would ca ```swift do { - var input = "1234 Hello"[...] - let number = try UInt8.parser().parse(&input)) + var input = "1234 Hello"[...].utf8 + let number = try UInt8.parser().parse(&input) } catch { print(error) @@ -77,7 +77,7 @@ For example, we could construct a parser that consumes a single uncommented line for a prefix: ```swift -let uncommentedLine = Prefix { $0 != "\n" } +let uncommentedLine = Prefix { $0 != "\n" } .compactMap { $0.starts(with: "//") ? nil : $0 } try uncommentedLine.parse("// let x = 1") @@ -127,7 +127,7 @@ struct User { var isAdmin: Bool } -let user = Parse(User.init(id:name:isAdmin:)) { +let user = Parse(input: Substring.self, User.init(id:name:isAdmin:)) { Int.parser() "," Prefix { $0 != "," }.map(String.init) @@ -206,7 +206,7 @@ struct Digits: Parser { If we swap out the `Int.parser()` for a `Digits` parser in `user`: ```swift -let user = Parse(User.init) { +let user = Parse(input: Substring.self, User.init) { Digits() "," Prefix { $0 != "," }.map(String.init) diff --git a/Sources/Parsing/Documentation.docc/Articles/GettingStarted.md b/Sources/Parsing/Documentation.docc/Articles/GettingStarted.md index 72b097b22a..2d42b36e5c 100644 --- a/Sources/Parsing/Documentation.docc/Articles/GettingStarted.md +++ b/Sources/Parsing/Documentation.docc/Articles/GettingStarted.md @@ -69,12 +69,16 @@ as an entry point into describing a list of parsers that you want to run one aft consume from an input: ```swift -let user = Parse { +let user = Parse(input: Substring.self) { Int.parser() "," } ``` +> Note: This parsing library is quite general, allowing one to parse _any_ kind of input into +_any_ kind of output. For this reason we sometimes need to specify the exact input type the parser +can process, in this case substrings. + Already this can consume the leading integer and comma from the beginning of the input: ```swift @@ -89,7 +93,7 @@ Next we want to take everything up until the next comma for the user's name, and comma: ```swift -let user = Parse { +let user = Parse(input: Substring.self) { Int.parser() "," Prefix { $0 != "," } @@ -100,7 +104,7 @@ let user = Parse { And then we want to take the boolean at the end of the row for the user's admin status: ```swift -let user = Parse { +let user = Parse(input: Substring.self) { Int.parser() "," Prefix { $0 != "," } @@ -113,7 +117,7 @@ Currently this will parse a tuple `(Int, Substring, Bool)` from the input, and w that to turn it into a `User`: ```swift -let user = Parse { +let user = Parse(input: Substring.self) { Int.parser() "," Prefix { $0 != "," } @@ -127,7 +131,7 @@ To make the data we are parsing to more prominent, we can instead pass the trans first argument to `Parse`: ```swift -let user = Parse { +let user = Parse(input: Substring.self) { User(id: $0, name: String($1), isAdmin: $2) } with: { Int.parser() @@ -142,7 +146,7 @@ Or we can pass the `User` initializer to `Parse` in a point-free style by first `Prefix` parser's output from a `Substring` to a `String`: ```swift -let user = Parse(User.init(id:name:isAdmin:)) { +let user = Parse(input: Substring.self, User.init(id:name:isAdmin:)) { Int.parser() "," Prefix { $0 != "," }.map(String.init) diff --git a/Sources/Parsing/Documentation.docc/Parsing.md b/Sources/Parsing/Documentation.docc/Parsing.md index 1cde7a3a14..7f97e7661f 100644 --- a/Sources/Parsing/Documentation.docc/Parsing.md +++ b/Sources/Parsing/Documentation.docc/Parsing.md @@ -33,7 +33,7 @@ A parser can be constructed for transforming the input string into an array of u and fluent API: ```swift -let user = Parse(User.init) { +let user = Parse(input: Substring.self, User.init) { Int.parser() "," Prefix { $0 != "," }.map(String.init) @@ -52,7 +52,7 @@ let users = Many { try users.parse(input) // [User(id: 1, name: "Blob", isAdmin: true), ...] ``` -This says that to parse a user we: +This says that to parse a user from a `Substring` we: * Parse and consume an integer from the beginning of the input * then a comma @@ -99,6 +99,7 @@ to learn in order to performantly parse larger inputs. * * * +* ## See Also diff --git a/Sources/Parsing/Internal/Deprecations.swift b/Sources/Parsing/Internal/Deprecations.swift index 14feab02c8..904f1f1c66 100644 --- a/Sources/Parsing/Internal/Deprecations.swift +++ b/Sources/Parsing/Internal/Deprecations.swift @@ -1,3 +1,61 @@ +import Foundation + +// NB: Deprecated after 0.11.0 + +extension Bool { + @available(*, deprecated, message: "Delete 'of: Substring.self' to silence this warning.") + @inlinable + public static func parser( + of inputType: Substring.Type + ) -> From< + Conversions.SubstringToUTF8View, Substring.UTF8View, Parsers.BoolParser + > { + From(.utf8) { Parsers.BoolParser() } + } +} + +extension BinaryFloatingPoint where Self: LosslessStringConvertible { + @_disfavoredOverload + @available(*, deprecated, message: "Delete 'of: Substring.self' to silence this warning.") + @inlinable + public static func parser( + of inputType: Substring.Type + ) -> From< + Conversions.SubstringToUTF8View, + Substring.UTF8View, + Parsers.FloatParser + > { + From(.utf8) { Parsers.FloatParser() } + } +} + +extension FixedWidthInteger { + @_disfavoredOverload + @available(*, deprecated, message: "Delete 'of: Substring.self' to silence this warning.") + @inlinable + public static func parser( + of inputType: Substring.Type, + radix: Int = 10 + ) -> From< + Conversions.SubstringToUTF8View, Substring.UTF8View, Parsers.IntParser + > { + From(.utf8) { Parsers.IntParser(radix: radix) } + } +} + +extension UUID { + @_disfavoredOverload + @available(*, deprecated, message: "Delete 'of: Substring.self' to silence this warning.") + @inlinable + public static func parser( + of inputType: Substring.Type + ) -> From< + Conversions.SubstringToUTF8View, Substring.UTF8View, Parsers.UUIDParser + > { + From(.utf8) { Parsers.UUIDParser() } + } +} + // NB: Deprecated after 0.8.0 extension Many where Printability == Never { @@ -11,9 +69,9 @@ extension Many where Printability == Never { atLeast minimum: Int, atMost maximum: Int, _ updateAccumulatingResult: @escaping (inout Result, Element.Output) throws -> Void, - @ParserBuilder element: () -> Element, - @ParserBuilder separator: () -> Separator, - @ParserBuilder terminator: () -> Terminator + @ParserBuilder element: () -> Element, + @ParserBuilder separator: () -> Separator, + @ParserBuilder terminator: () -> Terminator ) { self.init( minimum...maximum, @@ -34,9 +92,9 @@ extension Many where Printability == Never { into initialResult: Result, atLeast minimum: Int, _ updateAccumulatingResult: @escaping (inout Result, Element.Output) throws -> Void, - @ParserBuilder element: () -> Element, - @ParserBuilder separator: () -> Separator, - @ParserBuilder terminator: () -> Terminator + @ParserBuilder element: () -> Element, + @ParserBuilder separator: () -> Separator, + @ParserBuilder terminator: () -> Terminator ) { self.init( minimum..., @@ -57,9 +115,9 @@ extension Many where Printability == Never { into initialResult: Result, atMost maximum: Int, _ updateAccumulatingResult: @escaping (inout Result, Element.Output) throws -> Void, - @ParserBuilder element: () -> Element, - @ParserBuilder separator: () -> Separator, - @ParserBuilder terminator: () -> Terminator + @ParserBuilder element: () -> Element, + @ParserBuilder separator: () -> Separator, + @ParserBuilder terminator: () -> Terminator ) { self.init( ...maximum, @@ -88,7 +146,7 @@ where atLeast minimum: Int, atMost maximum: Int, _ updateAccumulatingResult: @escaping (inout Result, Element.Output) throws -> Void, - @ParserBuilder element: () -> Element + @ParserBuilder element: () -> Element ) { self.init( minimum...maximum, @@ -107,7 +165,7 @@ where into initialResult: Result, atLeast minimum: Int, _ updateAccumulatingResult: @escaping (inout Result, Element.Output) throws -> Void, - @ParserBuilder element: () -> Element + @ParserBuilder element: () -> Element ) { self.init( minimum..., @@ -126,7 +184,7 @@ where into initialResult: Result, atMost maximum: Int, _ updateAccumulatingResult: @escaping (inout Result, Element.Output) throws -> Void, - @ParserBuilder element: () -> Element + @ParserBuilder element: () -> Element ) { self.init( ...maximum, @@ -148,8 +206,8 @@ extension Many where Separator == Always, Printability == Never { atLeast minimum: Int, atMost maximum: Int, _ updateAccumulatingResult: @escaping (inout Result, Element.Output) throws -> Void, - @ParserBuilder element: () -> Element, - @ParserBuilder terminator: () -> Terminator + @ParserBuilder element: () -> Element, + @ParserBuilder terminator: () -> Terminator ) { self.init( minimum...maximum, @@ -169,8 +227,8 @@ extension Many where Separator == Always, Printability == Never { into initialResult: Result, atLeast minimum: Int, _ updateAccumulatingResult: @escaping (inout Result, Element.Output) throws -> Void, - @ParserBuilder element: () -> Element, - @ParserBuilder terminator: () -> Terminator + @ParserBuilder element: () -> Element, + @ParserBuilder terminator: () -> Terminator ) { self.init( minimum..., @@ -190,8 +248,8 @@ extension Many where Separator == Always, Printability == Never { into initialResult: Result, atMost maximum: Int, _ updateAccumulatingResult: @escaping (inout Result, Element.Output) throws -> Void, - @ParserBuilder element: () -> Element, - @ParserBuilder terminator: () -> Terminator + @ParserBuilder element: () -> Element, + @ParserBuilder terminator: () -> Terminator ) { self.init( ...maximum, @@ -214,9 +272,9 @@ extension Many where Terminator == Always, Printability == Never { atLeast minimum: Int, atMost maximum: Int, _ updateAccumulatingResult: @escaping (inout Result, Element.Output) throws -> Void, - @ParserBuilder element: () -> Element, - @ParserBuilder separator: () -> Separator - ) { + @ParserBuilder element: () -> Element, + @ParserBuilder separator: () -> Separator + ) where Element.Input == Input, Separator.Input == Input { self.init( minimum...maximum, into: initialResult, @@ -235,9 +293,9 @@ extension Many where Terminator == Always, Printability == Never { into initialResult: Result, atLeast minimum: Int, _ updateAccumulatingResult: @escaping (inout Result, Element.Output) throws -> Void, - @ParserBuilder element: () -> Element, - @ParserBuilder separator: () -> Separator - ) { + @ParserBuilder element: () -> Element, + @ParserBuilder separator: () -> Separator + ) where Element.Input == Input, Separator.Input == Input { self.init( minimum..., into: initialResult, @@ -256,9 +314,9 @@ extension Many where Terminator == Always, Printability == Never { into initialResult: Result, atMost maximum: Int, _ updateAccumulatingResult: @escaping (inout Result, Element.Output) throws -> Void, - @ParserBuilder element: () -> Element, - @ParserBuilder separator: () -> Separator - ) { + @ParserBuilder element: () -> Element, + @ParserBuilder separator: () -> Separator + ) where Element.Input == Input, Separator.Input == Input { self.init( ...maximum, into: initialResult, @@ -278,10 +336,10 @@ extension Many where Result == [Element.Output], Printability == Void { public init( atLeast minimum: Int, atMost maximum: Int, - @ParserBuilder element: () -> Element, - @ParserBuilder separator: () -> Separator, - @ParserBuilder terminator: () -> Terminator - ) { + @ParserBuilder element: () -> Element, + @ParserBuilder separator: () -> Separator, + @ParserBuilder terminator: () -> Terminator + ) where Element.Input == Input, Separator.Input == Input, Terminator.Input == Input { self.init( minimum...maximum, element: element, @@ -297,10 +355,10 @@ extension Many where Result == [Element.Output], Printability == Void { @inlinable public init( atLeast minimum: Int, - @ParserBuilder element: () -> Element, - @ParserBuilder separator: () -> Separator, - @ParserBuilder terminator: () -> Terminator - ) { + @ParserBuilder element: () -> Element, + @ParserBuilder separator: () -> Separator, + @ParserBuilder terminator: () -> Terminator + ) where Element.Input == Input, Separator.Input == Input, Terminator.Input == Input { self.init( minimum..., element: element, @@ -316,10 +374,10 @@ extension Many where Result == [Element.Output], Printability == Void { @inlinable public init( atMost maximum: Int, - @ParserBuilder element: () -> Element, - @ParserBuilder separator: () -> Separator, - @ParserBuilder terminator: () -> Terminator - ) { + @ParserBuilder element: () -> Element, + @ParserBuilder separator: () -> Separator, + @ParserBuilder terminator: () -> Terminator + ) where Element.Input == Input, Separator.Input == Input, Terminator.Input == Input { self.init( ...maximum, element: element, @@ -344,7 +402,7 @@ where public init( atLeast minimum: Int, atMost maximum: Int, - @ParserBuilder element: () -> Element + @ParserBuilder element: () -> Element ) { self.init( minimum...maximum, @@ -359,7 +417,7 @@ where @inlinable public init( atLeast minimum: Int, - @ParserBuilder element: () -> Element + @ParserBuilder element: () -> Element ) { self.init( minimum..., @@ -374,7 +432,7 @@ where @inlinable public init( atMost maximum: Int, - @ParserBuilder element: () -> Element + @ParserBuilder element: () -> Element ) { self.init( ...maximum, @@ -397,8 +455,8 @@ where public init( atLeast minimum: Int, atMost maximum: Int, - @ParserBuilder element: () -> Element, - @ParserBuilder terminator: () -> Terminator + @ParserBuilder element: () -> Element, + @ParserBuilder terminator: () -> Terminator ) { self.init( minimum...maximum, @@ -414,8 +472,8 @@ where @inlinable public init( atLeast minimum: Int, - @ParserBuilder element: () -> Element, - @ParserBuilder terminator: () -> Terminator + @ParserBuilder element: () -> Element, + @ParserBuilder terminator: () -> Terminator ) { self.init( minimum..., @@ -431,8 +489,8 @@ where @inlinable public init( atMost maximum: Int, - @ParserBuilder element: () -> Element, - @ParserBuilder terminator: () -> Terminator + @ParserBuilder element: () -> Element, + @ParserBuilder terminator: () -> Terminator ) { self.init( ...maximum, @@ -456,9 +514,9 @@ where public init( atLeast minimum: Int, atMost maximum: Int, - @ParserBuilder element: () -> Element, - @ParserBuilder separator: () -> Separator - ) { + @ParserBuilder element: () -> Element, + @ParserBuilder separator: () -> Separator + ) where Element.Input == Input, Separator.Input == Input { self.init( minimum...maximum, element: element, @@ -473,9 +531,9 @@ where @inlinable public init( atLeast minimum: Int, - @ParserBuilder element: () -> Element, - @ParserBuilder separator: () -> Separator - ) { + @ParserBuilder element: () -> Element, + @ParserBuilder separator: () -> Separator + ) where Element.Input == Input, Separator.Input == Input { self.init( minimum..., element: element, @@ -490,9 +548,9 @@ where @inlinable public init( atMost maximum: Int, - @ParserBuilder element: () -> Element, - @ParserBuilder separator: () -> Separator - ) { + @ParserBuilder element: () -> Element, + @ParserBuilder separator: () -> Separator + ) where Element.Input == Input, Separator.Input == Input { self.init( ...maximum, element: element, @@ -720,7 +778,7 @@ where SubstringParser.Input == Substring { @available(*, deprecated, message: "Use 'From(.substring)' instead.") extension FromSubstring where Input == ArraySlice { @inlinable - public init(@ParserBuilder _ build: () -> SubstringParser) { + public init(@ParserBuilder _ build: () -> SubstringParser) { self.substringParser = build() self.toSubstring = { Substring(decoding: $0, as: UTF8.self) } self.fromSubstring = { ArraySlice($0.utf8) } @@ -730,7 +788,7 @@ extension FromSubstring where Input == ArraySlice { @available(*, deprecated, message: "Use 'From(.substring)' instead.") extension FromSubstring where Input == Substring.UnicodeScalarView { @inlinable - public init(@ParserBuilder _ build: () -> SubstringParser) { + public init(@ParserBuilder _ build: () -> SubstringParser) { self.substringParser = build() self.toSubstring = Substring.init self.fromSubstring = \.unicodeScalars @@ -740,7 +798,7 @@ extension FromSubstring where Input == Substring.UnicodeScalarView { @available(*, deprecated, message: "Use 'From(.substring)' instead.") extension FromSubstring where Input == Substring.UTF8View { @inlinable - public init(@ParserBuilder _ build: () -> SubstringParser) { + public init(@ParserBuilder _ build: () -> SubstringParser) { self.substringParser = build() self.toSubstring = Substring.init self.fromSubstring = \.utf8 @@ -765,7 +823,7 @@ where UnicodeScalarsParser.Input == Substring.UnicodeScalarView { @available(*, deprecated, message: "Use 'From(.unicodeScalars)' instead.") extension FromUnicodeScalarView where Input == ArraySlice { @inlinable - public init(@ParserBuilder _ build: () -> UnicodeScalarsParser) { + public init(@ParserBuilder _ build: () -> UnicodeScalarsParser) { self.unicodeScalarsParser = build() self.toUnicodeScalars = { Substring(decoding: $0, as: UTF8.self).unicodeScalars } self.fromUnicodeScalars = { ArraySlice(Substring($0).utf8) } @@ -775,7 +833,7 @@ extension FromUnicodeScalarView where Input == ArraySlice { @available(*, deprecated, message: "Use 'From(.unicodeScalars)' instead.") extension FromUnicodeScalarView where Input == Substring { @inlinable - public init(@ParserBuilder _ build: () -> UnicodeScalarsParser) { + public init(@ParserBuilder _ build: () -> UnicodeScalarsParser) { self.unicodeScalarsParser = build() self.toUnicodeScalars = \.unicodeScalars self.fromUnicodeScalars = Substring.init @@ -785,7 +843,7 @@ extension FromUnicodeScalarView where Input == Substring { @available(*, deprecated, message: "Use 'From(.unicodeScalars)' instead.") extension FromUnicodeScalarView where Input == Substring.UTF8View { @inlinable - public init(@ParserBuilder _ build: () -> UnicodeScalarsParser) { + public init(@ParserBuilder _ build: () -> UnicodeScalarsParser) { self.unicodeScalarsParser = build() self.toUnicodeScalars = { Substring($0).unicodeScalars } self.fromUnicodeScalars = { Substring($0).utf8 } @@ -810,7 +868,7 @@ where UTF8Parser.Input == Substring.UTF8View { @available(*, deprecated, message: "Use 'From(.utf8)' instead.") extension FromUTF8View where Input == Substring { @inlinable - public init(@ParserBuilder _ build: () -> UTF8Parser) { + public init(@ParserBuilder _ build: () -> UTF8Parser) { self.utf8Parser = build() self.toUTF8 = \.utf8 self.fromUTF8 = Substring.init @@ -820,7 +878,7 @@ extension FromUTF8View where Input == Substring { @available(*, deprecated, message: "Use 'From(.utf8)' instead.") extension FromUTF8View where Input == Substring.UnicodeScalarView { @inlinable - public init(@ParserBuilder _ build: () -> UTF8Parser) { + public init(@ParserBuilder _ build: () -> UTF8Parser) { self.utf8Parser = build() self.toUTF8 = { Substring($0).utf8 } self.fromUTF8 = { Substring($0).unicodeScalars } diff --git a/Sources/Parsing/Parser.swift b/Sources/Parsing/Parser.swift index eb8d0630eb..a944e68281 100644 --- a/Sources/Parsing/Parser.swift +++ b/Sources/Parsing/Parser.swift @@ -1,51 +1,85 @@ -#if swift(>=5.7) - /// Declares a type that can incrementally parse an `Output` value from an `Input` value. - /// - /// A parser attempts to parse a nebulous piece of data, represented by the `Input` associated - /// type, into something more well-structured, represented by the `Output` associated type. The - /// parser implements the ``parse(_:)-76tcw`` method, which is handed an `inout Input`, and its - /// job is to turn this into an `Output` if possible, or throw an error if it cannot. - /// - /// The argument of the ``parse(_:)-76tcw`` function is `inout` because a parser will usually - /// consume some of the input in order to produce an output. For example, we can use an - /// `Int.parser()` parser to extract an integer from the beginning of a substring and consume that - /// portion of the string: +/// Declares a type that can incrementally parse an `Output` value from an `Input` value. +/// +/// A parser attempts to parse a nebulous piece of data, represented by the `Input` associated +/// type, into something more well-structured, represented by the `Output` associated type. The +/// parser implements the ``parse(_:)-76tcw`` method, which is handed an `inout Input`, and its +/// job is to turn this into an `Output` if possible, or throw an error if it cannot. +/// +/// The argument of the ``parse(_:)-76tcw`` function is `inout` because a parser will usually +/// consume some of the input in order to produce an output. For example, we can use an +/// `Int.parser()` parser to extract an integer from the beginning of a substring and consume that +/// portion of the string: +/// +/// ```swift +/// var input: Substring = "123 Hello world" +/// +/// try Int.parser().parse(&input) // 123 +/// input // " Hello world" +/// ``` +/// +/// Note that this parser works on `Substring` rather than `String` because substrings expose +/// efficient ways of removing characters from its beginning. Substrings are "views" into a +/// string, specified by start and end indices. Operations like `removeFirst`, `removeLast` and +/// others can be implemented efficiently on substrings because they simply move the start and end +/// indices, whereas their implementation on strings must make a copy of the string with the +/// characters removed. +@rethrows public protocol Parser { + /// The type of values this parser parses from. + associatedtype Input + + /// The type of values parsed by this parser. + associatedtype Output + + // NB: For Xcode to favor autocompleting `var body: Body` over `var body: Never` we must use a + // type alias. + associatedtype _Body + + /// A type representing the body of this parser. + typealias Body = _Body + + /// Attempts to parse a nebulous piece of data into something more well-structured. Typically + /// you only call this from other `Parser` conformances, not when you want to parse a concrete + /// input. /// - /// ```swift - /// var input: Substring = "123 Hello world" + /// - Parameter input: A nebulous, mutable piece of data to be incrementally parsed. + /// - Returns: A more well-structured value parsed from the given input. + func parse(_ input: inout Input) throws -> Output + + /// The content and behavior of a parser that is composed from other parsers. /// - /// try Int.parser().parse(&input) // 123 - /// input // " Hello world" - /// ``` + /// Implement this requirement when you want to incorporate the behavior of other parsers + /// together. /// - /// Note that this parser works on `Substring` rather than `String` because substrings expose - /// efficient ways of removing characters from its beginning. Substrings are "views" into a - /// string, specified by start and end indices. Operations like `removeFirst`, `removeLast` and - /// others can be implemented efficiently on substrings because they simply move the start and end - /// indices, whereas their implementation on strings must make a copy of the string with the - /// characters removed. - @rethrows public protocol Parser { - /// The type of values this parser parses from. - associatedtype Input + /// Do not invoke this property directly. + @ParserBuilder + var body: Body { get } +} - /// The type of values parsed by this parser. - associatedtype Output +extension Parser where Body == Never { + /// A non-existent body. + /// + /// > Warning: Do not invoke this property directly. It will trigger a fatal error at runtime. + @_transparent + public var body: Body { + fatalError( + """ + '\(Self.self)' has no body. … - /// Attempts to parse a nebulous piece of data into something more well-structured. Typically - /// you only call this from other `Parser` conformances, not when you want to parse a concrete - /// input. - /// - /// - Parameter input: A nebulous, mutable piece of data to be incrementally parsed. - /// - Returns: A more well-structured value parsed from the given input. - func parse(_ input: inout Input) throws -> Output + Do not access a parser's 'body' property directly, as it may not exist. To run a parser, \ + call 'Parser.parse(_:)', instead. + """ + ) } -#else - @rethrows public protocol Parser { - associatedtype Input - associatedtype Output - func parse(_ input: inout Input) throws -> Output +} + +extension Parser where Body: Parser, Body.Input == Input, Body.Output == Output { + // NB: This can't be `rethrows` do to a bug that swallows `throws` even when it's needed. + @inlinable + @inline(__always) + public func parse(_ input: inout Body.Input) throws -> Body.Output { + try self.body.parse(&input) } -#endif +} extension Parser { /// Parse an input value into an output. This method is more ergonomic to use than diff --git a/Sources/Parsing/ParserPrinter.swift b/Sources/Parsing/ParserPrinter.swift index 2c9d5b41b3..51926a95eb 100644 --- a/Sources/Parsing/ParserPrinter.swift +++ b/Sources/Parsing/ParserPrinter.swift @@ -1,23 +1,25 @@ -#if swift(>=5.7) - /// A ``Parser`` that can incrementally "print" an output value back into an input. +/// A ``Parser`` that can incrementally "print" an output value back into an input. +/// +/// > Note: Printing is the reverse operation of parsing, so the `Input` is essentially built up +/// > in reverse. As such, new values should be prepended to the front of the input. This allows +/// > parsers to check that the already-printed values match what is expected for any given +/// > ``Parser``. +@rethrows public protocol ParserPrinter: Parser { + /// Attempts to print a well-structured piece of data into something more nebulous. /// - /// > Note: Printing is the reverse operation of parsing, so the `Input` is essentially built up - /// > in reverse. As such, new values should be prepended to the front of the input. This allows - /// > parsers to check that the already-printed values match what is expected for any given - /// > ``Parser``. - @rethrows public protocol ParserPrinter: Parser { - /// Attempts to print a well-structured piece of data into something more nebulous. - /// - /// - Parameters - /// - output: A well-structured value to be printed to the given input. - /// - input: A nebulous, mutable piece of data to be incrementally printed into. - func print(_ output: Output, into input: inout Input) throws - } -#else - @rethrows public protocol ParserPrinter: Parser { - func print(_ output: Output, into input: inout Input) throws + /// - Parameters + /// - output: A well-structured value to be printed to the given input. + /// - input: A nebulous, mutable piece of data to be incrementally printed into. + func print(_ output: Output, into input: inout Input) throws +} + +extension ParserPrinter where Body: ParserPrinter, Body.Input == Input, Body.Output == Output { + // NB: This can't be `rethrows` do to a bug that swallows `throws` even when it's needed. + @inlinable + public func print(_ output: Output, into input: inout Input) throws { + try self.body.print(output, into: &input) } -#endif +} extension ParserPrinter where Input: _EmptyInitializable { /// Attempts to print a well-structured piece of data to something more nebulous. diff --git a/Sources/Parsing/ParserPrinters/Always.swift b/Sources/Parsing/ParserPrinters/Always.swift index 173b420a23..3f97bdd94c 100644 --- a/Sources/Parsing/ParserPrinters/Always.swift +++ b/Sources/Parsing/ParserPrinters/Always.swift @@ -37,7 +37,7 @@ /// } /// /// extension Many where Separator == Always, Terminator == Always { -/// init(@ParserBuilder element: () -> Element) { +/// init(@ParserBuilder element: () -> Element) { /// self.element = element() /// self.separator = Always(()) /// self.terminator = Always(()) @@ -78,20 +78,6 @@ public struct Always: ParserPrinter { public func print(_ output: Output, into input: inout Input) {} } -extension Always where Input == Substring { - @inlinable - public init(_ output: Output) { - self.output = output - } -} - -extension Always where Input == Substring.UTF8View { - @inlinable - public init(_ output: Output) { - self.output = output - } -} - extension Parsers { public typealias Always = Parsing.Always // NB: Convenience type alias for discovery } diff --git a/Sources/Parsing/ParserPrinters/Backtracking.swift b/Sources/Parsing/ParserPrinters/Backtracking.swift index b835579a0d..6c2e4b0823 100644 --- a/Sources/Parsing/ParserPrinters/Backtracking.swift +++ b/Sources/Parsing/ParserPrinters/Backtracking.swift @@ -4,11 +4,11 @@ /// Use this parser if you want to manually manage the backtracking behavior of your parsers. /// Another tool for managing backtracking is the ``OneOf`` parser. Also see the /// article for more information on backtracking. -public struct Backtracking: Parser { +public struct Backtracking: Parser where Upstream.Input == Input { public let upstream: Upstream public init( - @ParserBuilder upstream: () -> Upstream + @ParserBuilder upstream: () -> Upstream ) { self.upstream = upstream() } diff --git a/Sources/Parsing/ParserPrinters/Bool.swift b/Sources/Parsing/ParserPrinters/Bool.swift index 4e290ae5de..eb54a5abee 100644 --- a/Sources/Parsing/ParserPrinters/Bool.swift +++ b/Sources/Parsing/ParserPrinters/Bool.swift @@ -12,40 +12,6 @@ extension Bool { ) -> Parsers.BoolParser { .init() } - - /// A parser that consumes a Boolean value from the beginning of a substring. - /// - /// This overload is provided to allow the `Input` generic to be inferred when it is `Substring`. - /// - /// See for more information about this parser. - /// - /// - Parameter inputType: The `Substring` type. This parameter is included to mirror the - /// interface that parses any collection of UTF-8 code units. - /// - Returns: A parser that consumes a Boolean value from the beginning of a substring. - @inlinable - public static func parser( - of inputType: Substring.Type = Substring.self - ) -> From> { - From(.utf8) { Parsers.BoolParser() } - } - - /// A parser that consumes a Boolean value from the beginning of a substring's UTF-8 view. - /// - /// This overload is provided to allow the `Input` generic to be inferred when it is - /// `Substring.UTF8View`. - /// - /// See for more information about this parser. - /// - /// - Parameter inputType: The `Substring.UTF8View` type. This parameter is included to mirror the - /// interface that parses any collection of UTF-8 code units. - /// - Returns: A parser that consumes a Boolean value from the beginning of a substring's UTF-8 - /// view. - @inlinable - public static func parser( - of inputType: Substring.UTF8View.Type = Substring.UTF8View.self - ) -> Parsers.BoolParser { - .init() - } } extension Parsers { diff --git a/Sources/Parsing/ParserPrinters/Consumed.swift b/Sources/Parsing/ParserPrinters/Consumed.swift index 2c0743a039..e2048c12c5 100644 --- a/Sources/Parsing/ParserPrinters/Consumed.swift +++ b/Sources/Parsing/ParserPrinters/Consumed.swift @@ -1,13 +1,14 @@ /// A parser that returns the subsequence of input consumed by another parser. -public struct Consumed: Parser +public struct Consumed: Parser where + Upstream.Input == Input, Upstream.Input: Collection, - Upstream.Input.SubSequence == Upstream.Input + Input.SubSequence == Input { public let upstream: Upstream @inlinable - public init(@ParserBuilder _ build: () -> Upstream) { + public init(@ParserBuilder _ build: () -> Upstream) { self.upstream = build() } diff --git a/Sources/Parsing/ParserPrinters/End.swift b/Sources/Parsing/ParserPrinters/End.swift index a2374433e8..b717105f5f 100644 --- a/Sources/Parsing/ParserPrinters/End.swift +++ b/Sources/Parsing/ParserPrinters/End.swift @@ -48,18 +48,6 @@ public struct End: ParserPrinter { } } -extension End where Input == Substring { - @_disfavoredOverload - @inlinable - public init() {} -} - -extension End where Input == Substring.UTF8View { - @_disfavoredOverload - @inlinable - public init() {} -} - extension Parsers { public typealias End = Parsing.End // NB: Convenience type alias for discovery } diff --git a/Sources/Parsing/ParserPrinters/First.swift b/Sources/Parsing/ParserPrinters/First.swift index 02beeb9e41..12835eb4ac 100644 --- a/Sources/Parsing/ParserPrinters/First.swift +++ b/Sources/Parsing/ParserPrinters/First.swift @@ -42,18 +42,6 @@ extension First: ParserPrinter where Input: PrependableCollection { } } -extension First where Input == Substring { - @_disfavoredOverload - @inlinable - public init() {} -} - -extension First where Input == Substring.UTF8View { - @_disfavoredOverload - @inlinable - public init() {} -} - extension Parsers { public typealias First = Parsing.First // NB: Convenience type alias for discovery } diff --git a/Sources/Parsing/ParserPrinters/Float.swift b/Sources/Parsing/ParserPrinters/Float.swift index ae76601a56..299a5f60f5 100644 --- a/Sources/Parsing/ParserPrinters/Float.swift +++ b/Sources/Parsing/ParserPrinters/Float.swift @@ -13,42 +13,6 @@ extension BinaryFloatingPoint where Self: LosslessStringConvertible { ) -> Parsers.FloatParser { .init() } - - /// A parser that consumes a floating-point number from the beginning of a substring. - /// - /// This overload is provided to allow the `Input` generic to be inferred when it is `Substring`. - /// - /// See for more information about this parser. - /// - /// - Parameter inputType: The `Substring` type. This parameter is included to mirror the - /// interface that parses any collection of UTF-8 code units. - /// - Returns: A parser that consumes a floating-point number from the beginning of a substring. - @_disfavoredOverload - @inlinable - public static func parser( - of inputType: Substring.Type = Substring.self - ) -> From> { - From(.utf8) { Parsers.FloatParser() } - } - - /// A parser that consumes a floating-point number from the beginning of a substring's UTF-8 view. - /// - /// This overload is provided to allow the `Input` generic to be inferred when it is - /// `Substring.UTF8View`. - /// - /// See for more information about this parser. - /// - /// - Parameter inputType: The `Substring.UTF8View` type. This parameter is included to mirror the - /// interface that parses any collection of UTF-8 code units. - /// - Returns: A parser that consumes a floating-point number from the beginning of a substring's - /// UTF-8 view. - @_disfavoredOverload - @inlinable - public static func parser( - of inputType: Substring.UTF8View.Type = Substring.UTF8View.self - ) -> Parsers.FloatParser { - .init() - } } extension Parsers { diff --git a/Sources/Parsing/ParserPrinters/From.swift b/Sources/Parsing/ParserPrinters/From.swift index c31f1da86f..1bbafe808c 100644 --- a/Sources/Parsing/ParserPrinters/From.swift +++ b/Sources/Parsing/ParserPrinters/From.swift @@ -1,5 +1,5 @@ -public struct From: ParserPrinter -where Upstream.Output == Downstream.Input { +public struct From: Parser +where Upstream.Output == DownstreamInput, Downstream.Input == DownstreamInput { @usableFromInline let conversion: Upstream @@ -7,7 +7,7 @@ where Upstream.Output == Downstream.Input { let parser: Downstream @inlinable - public init(_ conversion: Upstream, @ParserBuilder _ parser: () -> Downstream) { + public init(_ conversion: Upstream, @ParserBuilder _ parser: () -> Downstream) { self.conversion = conversion self.parser = parser() } @@ -19,7 +19,9 @@ where Upstream.Output == Downstream.Input { input = try self.conversion.unapply(parserInput) return output } +} +extension From: ParserPrinter where Downstream: ParserPrinter { @inlinable public func print(_ output: Downstream.Output, into input: inout Upstream.Input) rethrows { var parserInput = try self.conversion.apply(input) diff --git a/Sources/Parsing/ParserPrinters/Int.swift b/Sources/Parsing/ParserPrinters/Int.swift index fe30d79ee6..6c63c62978 100644 --- a/Sources/Parsing/ParserPrinters/Int.swift +++ b/Sources/Parsing/ParserPrinters/Int.swift @@ -17,52 +17,6 @@ extension FixedWidthInteger { ) -> Parsers.IntParser { .init(radix: radix) } - - /// A parser that consumes an integer (with an optional leading `+` or `-` sign for signed integer - /// types) from the beginning of a substring. - /// - /// This overload is provided to allow the `Input` generic to be inferred when it is `Substring`. - /// - /// See for more information about this parser. - /// - /// - Parameters: - /// - inputType: The `Substring` type. This parameter is included to mirror the interface that - /// parses any collection of UTF-8 code units. - /// - isSigned: If the parser will attempt to parse a leading `+` or `-` sign. - /// - radix: The radix, or base, to use for converting text to an integer value. `radix` must be - /// in the range `2...36`. - /// - Returns: A parser that consumes an integer from the beginning of a substring. - @_disfavoredOverload - @inlinable - public static func parser( - of inputType: Substring.Type = Substring.self, - radix: Int = 10 - ) -> From> { - From(.utf8) { Parsers.IntParser(radix: radix) } - } - - /// A parser that consumes an integer (with an optional leading `+` or `-` sign) from the - /// beginning of a substring's UTF-8 view. - /// - /// This overload is provided to allow the `Input` generic to be inferred when it is - /// `Substring.UTF8View`. - /// - /// See for more information about this parser. - /// - /// - Parameters: - /// - inputType: The `Substring.UTF8View` type. This parameter is included to mirror the - /// interface that parses any collection of UTF-8 code units. - /// - radix: The radix, or base, to use for converting text to an integer value. `radix` must be - /// in the range `2...36`. - /// - Returns: A parser that consumes an integer from the beginning of a substring's UTF-8 view. - @_disfavoredOverload - @inlinable - public static func parser( - of inputType: Substring.UTF8View.Type = Substring.UTF8View.self, - radix: Int = 10 - ) -> Parsers.IntParser { - .init(radix: radix) - } } extension Parsers { diff --git a/Sources/Parsing/ParserPrinters/Lazy.swift b/Sources/Parsing/ParserPrinters/Lazy.swift index 11a4f82674..a7d44beb6e 100644 --- a/Sources/Parsing/ParserPrinters/Lazy.swift +++ b/Sources/Parsing/ParserPrinters/Lazy.swift @@ -1,13 +1,45 @@ /// A parser that waits for a call to its ``parse(_:)`` method before running the given closure to /// create a parser for the given input. -public final class Lazy: Parser { +@available( + iOS, + deprecated: 9999, + message: + """ + Lazily evaluate a parser by specifying it in a computed 'Parser.body' property, instead. + """ +) +@available( + macOS, + deprecated: 9999, + message: + """ + Lazily evaluate a parser by specifying it in a computed 'Parser.body' property, instead. + """ +) +@available( + tvOS, + deprecated: 9999, + message: + """ + Lazily evaluate a parser by specifying it in a computed 'Parser.body' property, instead. + """ +) +@available( + watchOS, + deprecated: 9999, + message: + """ + Lazily evaluate a parser by specifying it in a computed 'Parser.body' property, instead. + """ +) +public final class Lazy: Parser where Input == LazyParser.Input { @usableFromInline internal var lazyParser: LazyParser? public let createParser: () -> LazyParser @inlinable - public init(@ParserBuilder createParser: @escaping () -> LazyParser) { + public init(@ParserBuilder createParser: @escaping () -> LazyParser) { self.createParser = createParser } diff --git a/Sources/Parsing/ParserPrinters/Many.swift b/Sources/Parsing/ParserPrinters/Many.swift index 213ff8b2ca..cc8ef3eac6 100644 --- a/Sources/Parsing/ParserPrinters/Many.swift +++ b/Sources/Parsing/ParserPrinters/Many.swift @@ -73,11 +73,12 @@ import Foundation /// // | ^ expected integer /// ``` public struct Many< - Element: Parser, Result, Separator: Parser, Terminator: Parser, Printability + Input, Element: Parser, Result, Separator: Parser, Terminator: Parser, Printability >: Parser where - Separator.Input == Element.Input, - Terminator.Input == Element.Input + Element.Input == Input, + Separator.Input == Input, + Terminator.Input == Input { public let element: Element public let initialResult: Result @@ -234,9 +235,9 @@ extension Many where Printability == Void { into initialResult: Result, _ updateAccumulatingResult: @escaping (inout Result, Element.Output) throws -> Void, decumulator: @escaping (Result) throws -> I, - @ParserBuilder element: () -> Element, - @ParserBuilder separator: () -> Separator, - @ParserBuilder terminator: () -> Terminator + @ParserBuilder element: () -> Element, + @ParserBuilder separator: () -> Separator, + @ParserBuilder terminator: () -> Terminator ) where I.Element == Element.Output { self.element = element() self.initialResult = initialResult @@ -265,9 +266,9 @@ extension Many where Printability == Void { into initialResult: Result, _ updateAccumulatingResult: @escaping (inout Result, Element.Output) throws -> Void, decumulator: @escaping (Result) throws -> I, - @ParserBuilder element: () -> Element, - @ParserBuilder separator: () -> Separator, - @ParserBuilder terminator: () -> Terminator + @ParserBuilder element: () -> Element, + @ParserBuilder separator: () -> Separator, + @ParserBuilder terminator: () -> Terminator ) where I.Element == Element.Output { self.init( 0..., @@ -300,9 +301,9 @@ extension Many where Printability == Never { _ length: R, into initialResult: Result, _ updateAccumulatingResult: @escaping (inout Result, Element.Output) throws -> Void, - @ParserBuilder element: () -> Element, - @ParserBuilder separator: () -> Separator, - @ParserBuilder terminator: () -> Terminator + @ParserBuilder element: () -> Element, + @ParserBuilder separator: () -> Separator, + @ParserBuilder terminator: () -> Terminator ) { self.element = element() self.initialResult = initialResult @@ -328,9 +329,9 @@ extension Many where Printability == Never { public init( into initialResult: Result, _ updateAccumulatingResult: @escaping (inout Result, Element.Output) throws -> Void, - @ParserBuilder element: () -> Element, - @ParserBuilder separator: () -> Separator, - @ParserBuilder terminator: () -> Terminator + @ParserBuilder element: () -> Element, + @ParserBuilder separator: () -> Separator, + @ParserBuilder terminator: () -> Terminator ) { self.init( 0..., @@ -368,7 +369,7 @@ where into initialResult: Result, _ updateAccumulatingResult: @escaping (inout Result, Element.Output) throws -> Void, decumulator: @escaping (Result) throws -> I, - @ParserBuilder element: () -> Element + @ParserBuilder element: () -> Element ) where I.Element == Element.Output { self.init( length, @@ -397,7 +398,7 @@ where into initialResult: Result, _ updateAccumulatingResult: @escaping (inout Result, Element.Output) throws -> Void, decumulator: @escaping (Result) throws -> I, - @ParserBuilder element: () -> Element + @ParserBuilder element: () -> Element ) where I.Element == Element.Output { self.init( 0..., @@ -433,7 +434,7 @@ where _ length: R, into initialResult: Result, _ updateAccumulatingResult: @escaping (inout Result, Element.Output) throws -> Void, - @ParserBuilder element: () -> Element + @ParserBuilder element: () -> Element ) { self.init( length, @@ -457,7 +458,7 @@ where public init( into initialResult: Result, _ updateAccumulatingResult: @escaping (inout Result, Element.Output) throws -> Void, - @ParserBuilder element: () -> Element + @ParserBuilder element: () -> Element ) { self.init( 0..., @@ -489,8 +490,8 @@ extension Many where Separator == Always, Printability == Void { into initialResult: Result, _ updateAccumulatingResult: @escaping (inout Result, Element.Output) throws -> Void, decumulator: @escaping (Result) throws -> I, - @ParserBuilder element: () -> Element, - @ParserBuilder terminator: () -> Terminator + @ParserBuilder element: () -> Element, + @ParserBuilder terminator: () -> Terminator ) where I.Element == Element.Output { self.init( length, @@ -519,8 +520,8 @@ extension Many where Separator == Always, Printability == Void { into initialResult: Result, _ updateAccumulatingResult: @escaping (inout Result, Element.Output) throws -> Void, decumulator: @escaping (Result) throws -> I, - @ParserBuilder element: () -> Element, - @ParserBuilder terminator: () -> Terminator + @ParserBuilder element: () -> Element, + @ParserBuilder terminator: () -> Terminator ) where I.Element == Element.Output { self.init( 0..., @@ -551,8 +552,8 @@ extension Many where Separator == Always, Printability == Never { _ length: R, into initialResult: Result, _ updateAccumulatingResult: @escaping (inout Result, Element.Output) throws -> Void, - @ParserBuilder element: () -> Element, - @ParserBuilder terminator: () -> Terminator + @ParserBuilder element: () -> Element, + @ParserBuilder terminator: () -> Terminator ) { self.init( length, @@ -577,8 +578,8 @@ extension Many where Separator == Always, Printability == Never { public init( into initialResult: Result, _ updateAccumulatingResult: @escaping (inout Result, Element.Output) throws -> Void, - @ParserBuilder element: () -> Element, - @ParserBuilder terminator: () -> Terminator + @ParserBuilder element: () -> Element, + @ParserBuilder terminator: () -> Terminator ) { self.init( 0..., @@ -611,8 +612,8 @@ extension Many where Terminator == Always, Printability == Void { into initialResult: Result, _ updateAccumulatingResult: @escaping (inout Result, Element.Output) throws -> Void, decumulator: @escaping (Result) throws -> I, - @ParserBuilder element: () -> Element, - @ParserBuilder separator: () -> Separator + @ParserBuilder element: () -> Element, + @ParserBuilder separator: () -> Separator ) where I.Element == Element.Output { self.init( length, @@ -641,8 +642,8 @@ extension Many where Terminator == Always, Printability == Void { into initialResult: Result, _ updateAccumulatingResult: @escaping (inout Result, Element.Output) throws -> Void, decumulator: @escaping (Result) throws -> I, - @ParserBuilder element: () -> Element, - @ParserBuilder separator: () -> Separator + @ParserBuilder element: () -> Element, + @ParserBuilder separator: () -> Separator ) where I.Element == Element.Output { self.init( 0..., @@ -673,8 +674,8 @@ extension Many where Terminator == Always, Printability == Never { _ length: R, into initialResult: Result, _ updateAccumulatingResult: @escaping (inout Result, Element.Output) throws -> Void, - @ParserBuilder element: () -> Element, - @ParserBuilder separator: () -> Separator + @ParserBuilder element: () -> Element, + @ParserBuilder separator: () -> Separator ) { self.init( length, @@ -699,8 +700,8 @@ extension Many where Terminator == Always, Printability == Never { public init( into initialResult: Result, _ updateAccumulatingResult: @escaping (inout Result, Element.Output) throws -> Void, - @ParserBuilder element: () -> Element, - @ParserBuilder separator: () -> Separator + @ParserBuilder element: () -> Element, + @ParserBuilder separator: () -> Separator ) { self.init( 0..., @@ -726,9 +727,9 @@ extension Many where Result == [Element.Output], Printability == Void { @inlinable public init( _ length: R, - @ParserBuilder element: () -> Element, - @ParserBuilder separator: () -> Separator, - @ParserBuilder terminator: () -> Terminator + @ParserBuilder element: () -> Element, + @ParserBuilder separator: () -> Separator, + @ParserBuilder terminator: () -> Terminator ) { self.init( length, @@ -751,9 +752,9 @@ extension Many where Result == [Element.Output], Printability == Void { /// - terminator: A parser that consumes any leftover input. @inlinable public init( - @ParserBuilder element: () -> Element, - @ParserBuilder separator: () -> Separator, - @ParserBuilder terminator: () -> Terminator + @ParserBuilder element: () -> Element, + @ParserBuilder separator: () -> Separator, + @ParserBuilder terminator: () -> Terminator ) { self.init( 0..., @@ -782,7 +783,7 @@ where @inlinable public init( _ length: R, - @ParserBuilder element: () -> Element + @ParserBuilder element: () -> Element ) { self.init( length, @@ -798,7 +799,7 @@ where /// /// - Parameter element: A parser to run multiple times to accumulate into a result. @inlinable - public init(@ParserBuilder element: () -> Element) { + public init(@ParserBuilder element: () -> Element) { self.init(0..., element: element) } } @@ -821,8 +822,8 @@ where @inlinable public init( _ length: R, - @ParserBuilder element: () -> Element, - @ParserBuilder terminator: () -> Terminator + @ParserBuilder element: () -> Element, + @ParserBuilder terminator: () -> Terminator ) { self.init( length, @@ -842,8 +843,8 @@ where /// - terminator: A parser that consumes any leftover input. @inlinable public init( - @ParserBuilder element: () -> Element, - @ParserBuilder terminator: () -> Terminator + @ParserBuilder element: () -> Element, + @ParserBuilder terminator: () -> Terminator ) { self.init( 0..., @@ -871,8 +872,8 @@ where @inlinable public init( _ length: R, - @ParserBuilder element: () -> Element, - @ParserBuilder separator: () -> Separator + @ParserBuilder element: () -> Element, + @ParserBuilder separator: () -> Separator ) { self.init( length, @@ -892,8 +893,8 @@ where /// - separator: A parser that consumes input between each parsed output. @inlinable public init( - @ParserBuilder element: () -> Element, - @ParserBuilder separator: () -> Separator + @ParserBuilder element: () -> Element, + @ParserBuilder separator: () -> Separator ) { self.init( 0..., diff --git a/Sources/Parsing/ParserPrinters/Not.swift b/Sources/Parsing/ParserPrinters/Not.swift index 0f251117b2..93d53e4817 100644 --- a/Sources/Parsing/ParserPrinters/Not.swift +++ b/Sources/Parsing/ParserPrinters/Not.swift @@ -16,7 +16,7 @@ /// // 1 | // let x = 1 /// // | ^^ expected not to be processed /// ``` -public struct Not: ParserPrinter { +public struct Not: ParserPrinter where Upstream.Input == Input { public let upstream: Upstream /// Creates a parser that succeeds if the given parser fails, and does not consume any input. @@ -24,7 +24,7 @@ public struct Not: ParserPrinter { /// - Parameter build: A parser that causes this parser to fail if it succeeds, or succeed if it /// fails. @inlinable - public init(@ParserBuilder _ build: () -> Upstream) { + public init(@ParserBuilder _ build: () -> Upstream) { self.upstream = build() } diff --git a/Sources/Parsing/ParserPrinters/OneOf.swift b/Sources/Parsing/ParserPrinters/OneOf.swift index e0c84f7c07..e15568a989 100644 --- a/Sources/Parsing/ParserPrinters/OneOf.swift +++ b/Sources/Parsing/ParserPrinters/OneOf.swift @@ -156,11 +156,16 @@ /// in the builder closure, it does _not_ undo the consumption of the last parser. If you want to /// enforce backtracking for the entire ``OneOf`` parser you need to further wrap it inside the /// ``Backtracking`` parser. -public struct OneOf: Parser { +public struct OneOf: Parser +where Parsers.Input == Input, Parsers.Output == Output { public let parsers: Parsers @inlinable - public init(@OneOfBuilder _ build: () -> Parsers) { + public init( + input inputType: Input.Type = Input.self, + output outputType: Output.Type = Output.self, + @OneOfBuilder _ build: () -> Parsers + ) { self.parsers = build() } diff --git a/Sources/Parsing/ParserPrinters/Optionally.swift b/Sources/Parsing/ParserPrinters/Optionally.swift index 01d7be5726..1a9058e7da 100644 --- a/Sources/Parsing/ParserPrinters/Optionally.swift +++ b/Sources/Parsing/ParserPrinters/Optionally.swift @@ -32,11 +32,11 @@ /// Int.parser() /// .replaceError(with: 0) /// ``` -public struct Optionally: Parser { +public struct Optionally: Parser where Wrapped.Input == Input { public let wrapped: Wrapped @inlinable - public init(@ParserBuilder _ build: () -> Wrapped) { + public init(@ParserBuilder _ build: () -> Wrapped) { self.wrapped = build() } diff --git a/Sources/Parsing/ParserPrinters/Parse.swift b/Sources/Parsing/ParserPrinters/Parse.swift index 06d4139412..b6dfd29e82 100644 --- a/Sources/Parsing/ParserPrinters/Parse.swift +++ b/Sources/Parsing/ParserPrinters/Parse.swift @@ -20,7 +20,7 @@ /// // 1 | (42,blob) /// // | ^ expected integer /// ``` -public struct Parse: Parser { +public struct Parse: Parser where Parsers.Input == Input { public let parsers: Parsers /// An entry point into ``ParserBuilder`` syntax. @@ -43,7 +43,10 @@ public struct Parse: Parser { /// /// - Parameter with: A parser builder that will accumulate non-void outputs in a tuple. @inlinable - public init(@ParserBuilder with build: () -> Parsers) { + public init( + input inputType: Input.Type = Input.self, + @ParserBuilder with build: () -> Parsers + ) { self.parsers = build() } @@ -77,8 +80,9 @@ public struct Parse: Parser { /// - with: A parser builder that will accumulate non-void outputs in a tuple. @inlinable public init( + input inputType: Input.Type = Input.self, _ transform: @escaping (Upstream.Output) -> NewOutput, - @ParserBuilder with build: () -> Upstream + @ParserBuilder with build: () -> Upstream ) where Parsers == Parsing.Parsers.Map { self.parsers = build().map(transform) } @@ -100,8 +104,9 @@ public struct Parse: Parser { /// ``` @inlinable public init( + input inputType: Input.Type = Input.self, _ output: NewOutput, - @ParserBuilder with build: () -> Upstream + @ParserBuilder with build: () -> Upstream ) where Parsers == Parsing.Parsers.MapConstant { self.parsers = build().map { output } } @@ -136,8 +141,9 @@ public struct Parse: Parser { /// - with: A parser builder that will accumulate non-void outputs in a tuple. @inlinable public init( + input inputType: Input.Type = Input.self, _ conversion: Downstream, - @ParserBuilder with build: () -> Upstream + @ParserBuilder with build: () -> Upstream ) where Parsers == Parsing.Parsers.MapConversion { self.parsers = build().map(conversion) } @@ -188,26 +194,32 @@ extension Parse: ParserPrinter where Parsers: ParserPrinter { /// /// `ParsePrint` is a type alias for the ``Parse`` parser with its underlying parser constrained to /// ``ParserPrinter``. -public struct ParsePrint: ParserPrinter { +public struct ParsePrint: ParserPrinter +where Input == ParserPrinters.Input { public let parserPrinters: ParserPrinters @inlinable - public init(@ParserBuilder with build: () -> ParserPrinters) { + public init( + input inputType: Input.Type = Input.self, + @ParserBuilder with build: () -> ParserPrinters + ) { self.parserPrinters = build() } @inlinable public init( + input inputType: Input.Type = Input.self, _ output: NewOutput, - @ParserBuilder with build: () -> Upstream + @ParserBuilder with build: () -> Upstream ) where ParserPrinters == Parsers.MapConstant { self.parserPrinters = build().map { output } } @inlinable public init( + input inputType: Input.Type = Input.self, _ conversion: Downstream, - @ParserBuilder with build: () -> Upstream + @ParserBuilder with build: () -> Upstream ) where ParserPrinters == Parsers.MapConversion { self.parserPrinters = build().map(conversion) } diff --git a/Sources/Parsing/ParserPrinters/ParseableFormatStyle.swift b/Sources/Parsing/ParserPrinters/ParseableFormatStyle.swift index 15aedd35e8..a5258dd4b3 100644 --- a/Sources/Parsing/ParserPrinters/ParseableFormatStyle.swift +++ b/Sources/Parsing/ParserPrinters/ParseableFormatStyle.swift @@ -1,4 +1,4 @@ -#if swift(>=5.7) && (os(iOS) || os(macOS) || os(tvOS) || os(watchOS)) +#if os(iOS) || os(macOS) || os(tvOS) || os(watchOS) import Foundation @available(iOS 16, macOS 13, tvOS 16, watchOS 9, *) diff --git a/Sources/Parsing/ParserPrinters/Peek.swift b/Sources/Parsing/ParserPrinters/Peek.swift index cafe33ebc8..3105e4af06 100644 --- a/Sources/Parsing/ParserPrinters/Peek.swift +++ b/Sources/Parsing/ParserPrinters/Peek.swift @@ -23,14 +23,14 @@ /// // 1 | 1_foo123 /// // | ^ expected 1 element satisfying predicate /// ``` -public struct Peek: ParserPrinter { +public struct Peek: ParserPrinter where Upstream.Input == Input { public let upstream: Upstream /// Construct a parser that runs the given parser, but does not consume any input. /// /// - Parameter build: A parser this parser wants to inspect. @inlinable - public init(@ParserBuilder _ build: () -> Upstream) { + public init(@ParserBuilder _ build: () -> Upstream) { self.upstream = build() } diff --git a/Sources/Parsing/ParserPrinters/Pipe.swift b/Sources/Parsing/ParserPrinters/Pipe.swift index 13f0f83c2d..7c043fb83a 100644 --- a/Sources/Parsing/ParserPrinters/Pipe.swift +++ b/Sources/Parsing/ParserPrinters/Pipe.swift @@ -31,7 +31,7 @@ extension Parser { /// - Parameter downstream: A parser that parses the output of this parser. /// - Returns: A parser that pipes this parser's output into another parser. @inlinable public func pipe( - @ParserBuilder _ build: () -> Downstream + @ParserBuilder _ build: () -> Downstream ) -> Parsers.Pipe { .init(upstream: self, downstream: build()) } @@ -39,8 +39,9 @@ extension Parser { extension Parser where Input: Collection { public func pipe( - @ParserBuilder _ build: () -> Downstream - ) -> Parsers.Pipe>> { + @ParserBuilder _ build: () -> Downstream + ) -> Parsers.Pipe.SkipSecond>> + { .init( upstream: self, downstream: .init(build(), Parsers.PipeEnd()) diff --git a/Sources/Parsing/ParserPrinters/Prefix.swift b/Sources/Parsing/ParserPrinters/Prefix.swift index ebc24ca2b4..b1e23af422 100644 --- a/Sources/Parsing/ParserPrinters/Prefix.swift +++ b/Sources/Parsing/ParserPrinters/Prefix.swift @@ -188,34 +188,6 @@ extension Prefix: ParserPrinter where Input: PrependableCollection { } } -extension Prefix where Input == Substring { - @_disfavoredOverload - @inlinable - public init(_ length: R, while predicate: ((Input.Element) -> Bool)? = nil) { - self.init(length, while: predicate) - } - - @_disfavoredOverload - @inlinable - public init(while predicate: @escaping (Input.Element) -> Bool) { - self.init(while: predicate) - } -} - -extension Prefix where Input == Substring.UTF8View { - @_disfavoredOverload - @inlinable - public init(_ length: R, while predicate: ((Input.Element) -> Bool)? = nil) { - self.init(length, while: predicate) - } - - @_disfavoredOverload - @inlinable - public init(while predicate: @escaping (Input.Element) -> Bool) { - self.init(while: predicate) - } -} - extension Parsers { public typealias Prefix = Parsing.Prefix // NB: Convenience type alias for discovery } diff --git a/Sources/Parsing/ParserPrinters/Rest.swift b/Sources/Parsing/ParserPrinters/Rest.swift index 153ec5188e..79a87dae38 100644 --- a/Sources/Parsing/ParserPrinters/Rest.swift +++ b/Sources/Parsing/ParserPrinters/Rest.swift @@ -71,18 +71,6 @@ extension Rest: ParserPrinter where Input: PrependableCollection { } } -extension Rest where Input == Substring { - @_disfavoredOverload - @inlinable - public init() {} -} - -extension Rest where Input == Substring.UTF8View { - @_disfavoredOverload - @inlinable - public init() {} -} - extension Parsers { public typealias Rest = Parsing.Rest // NB: Convenience type alias for discovery } diff --git a/Sources/Parsing/ParserPrinters/Skip.swift b/Sources/Parsing/ParserPrinters/Skip.swift index df5be070f7..9aca3bebf1 100644 --- a/Sources/Parsing/ParserPrinters/Skip.swift +++ b/Sources/Parsing/ParserPrinters/Skip.swift @@ -1,10 +1,10 @@ /// A parser that discards the output of another parser. -public struct Skip: Parser { +public struct Skip: Parser where Parsers.Input == Input { /// The parser from which this parser receives output. public let parsers: Parsers @inlinable - public init(@ParserBuilder _ build: () -> Parsers) { + public init(@ParserBuilder _ build: () -> Parsers) { self.parsers = build() } diff --git a/Sources/Parsing/ParserPrinters/UUID.swift b/Sources/Parsing/ParserPrinters/UUID.swift index 4355b9fad6..bb79d66d0c 100644 --- a/Sources/Parsing/ParserPrinters/UUID.swift +++ b/Sources/Parsing/ParserPrinters/UUID.swift @@ -19,38 +19,6 @@ extension UUID { ) -> Parsers.UUIDParser { .init() } - - /// A parser that consumes a hexadecimal UUID from the beginning of a substring. - /// - /// This overload is provided to allow the `Input` generic to be inferred when it is `Substring`. - /// - /// - Parameter inputType: The `Substring` type. This parameter is included to mirror the - /// interface that parses any collection of UTF-8 code units. - /// - Returns: A parser that consumes a hexadecimal UUID from the beginning of a substring. - @_disfavoredOverload - @inlinable - public static func parser( - of inputType: Substring.Type = Substring.self - ) -> From> { - From(.utf8) { Parsers.UUIDParser() } - } - - /// A parser that consumes a hexadecimal UUID from the beginning of a substring's UTF-8 view. - /// - /// This overload is provided to allow the `Input` generic to be inferred when it is - /// `Substring.UTF8View`. - /// - /// - Parameter inputType: The `Substring` type. This parameter is included to mirror the - /// interface that parses any collection of UTF-8 code units. - /// - Returns: A parser that consumes a hexadecimal UUID from the beginning of a substring's UTF-8 - /// view. - @_disfavoredOverload - @inlinable - public static func parser( - of inputType: Substring.UTF8View.Type = Substring.UTF8View.self - ) -> Parsers.UUIDParser { - .init() - } } extension Parsers { diff --git a/Sources/Parsing/ParserPrinters/Whitespace.swift b/Sources/Parsing/ParserPrinters/Whitespace.swift index 62b379b59d..c602697882 100644 --- a/Sources/Parsing/ParserPrinters/Whitespace.swift +++ b/Sources/Parsing/ParserPrinters/Whitespace.swift @@ -185,36 +185,6 @@ extension Whitespace { } } -extension Whitespace where InputToBytes == Conversions.SubstringToUTF8View { - @_disfavoredOverload - @inlinable - public init(_ configuration: Configuration = .all) where Length == PartialRangeFrom { - self.init(0..., configuration) - } - - @_disfavoredOverload - @inlinable - public init(_ length: Length, _ configuration: Configuration = .all) { - self.length = length - self.configuration = configuration - self.inputToBytes = .init() - } -} - -extension Whitespace where InputToBytes == Conversions.Identity { - @_disfavoredOverload - @inlinable - public init(_ configuration: Configuration = .all) where Length == PartialRangeFrom { - self.init(configuration) - } - - @_disfavoredOverload - @inlinable - public init(_ length: Length, _ configuration: Configuration = .all) { - self.init(length, configuration) - } -} - extension Parsers { public typealias Whitespace = Parsing.Whitespace // NB: Convenience type alias for discovery } diff --git a/Sources/Parsing/Parsers/FlatMap.swift b/Sources/Parsing/Parsers/FlatMap.swift index b41aacd0a2..7146490559 100644 --- a/Sources/Parsing/Parsers/FlatMap.swift +++ b/Sources/Parsing/Parsers/FlatMap.swift @@ -16,9 +16,9 @@ extension Parser { /// new parser. /// - Returns: A parser that transforms output from an upstream parser into a new parser. @inlinable - public func flatMap( - @ParserBuilder _ transform: @escaping (Output) -> NewParser - ) -> Parsers.FlatMap { + public func flatMap( + @ParserBuilder _ transform: @escaping (Output) -> NewParser + ) -> Parsers.FlatMap where Self.Input == Input { .init(upstream: self, transform: transform) } } diff --git a/Sources/Parsing/Parsers/Stream.swift b/Sources/Parsing/Parsers/Stream.swift index b230ae1d48..60f5198f01 100644 --- a/Sources/Parsing/Parsers/Stream.swift +++ b/Sources/Parsing/Parsers/Stream.swift @@ -30,11 +30,12 @@ /// /// try newlineSeparatedIntegers.parse(&stdin) /// ``` -public struct Stream: Parser where Parsers.Input: RangeReplaceableCollection { +public struct Stream: Parser +where Parsers.Input == Input { public let parsers: Parsers @inlinable - public init(@ParserBuilder build: () -> Parsers) { + public init(@ParserBuilder build: () -> Parsers) { self.parsers = build() } diff --git a/Sources/Parsing/PrependableCollection.swift b/Sources/Parsing/PrependableCollection.swift index 9d9835aaea..0f6fa585e7 100644 --- a/Sources/Parsing/PrependableCollection.swift +++ b/Sources/Parsing/PrependableCollection.swift @@ -1,95 +1,89 @@ import Foundation -#if swift(>=5.7) - /// A collection that supports empty initialization and the ability to prepend a sequence of - /// elements of elements to itself. - /// - /// `PrependableCollection` is a specialized subset of `RangeReplaceableCollection` that is tuned - /// to incremental printing. - /// - /// In fact, any `RangeReplaceableCollection` can get a conformance for free: - /// - /// ```swift - /// extension MyRangeReplaceableCollection: PrependableCollection {} - /// ``` - /// - /// Because it is also less strict than `RangeReplaceableCollection`, it is an appropriate - /// protocol to conform to for types that cannot and should not conform to - /// `RangeReplaceableCollection` directly. - /// - /// For example, `Substring.UTF8View` is a common input for string parsers to parse from, but it - /// does not conform to `RangeReplaceableCollection`. It does, however, conform to - /// `PrependableCollection` by validating and prepending the given UTF-8 bytes to its underlying - /// substring. So in order to write a parser against generic sequences of UTF-8 bytes, you would - /// constrain its input against `PrependableCollection`. - /// - /// For example the following `Digits` parser is generic over an `Collection` of bytes, and its - /// printer conformance further constraints its input to be prependable. - /// - /// ```swift - /// struct Digits: Parser - /// where - /// Input.Element == UTF8.CodeUnit, // Required for working with a collection of bytes - /// Input.SubSequence == Input // Required for the parser to consume from input - /// { - /// func parse(_ input: inout Input) throws -> Int { - /// // Collect all bytes between ASCII "0" and "9" - /// let prefix = input.prefix(while: { $0 >= .init(ascii: "0") && $0 <= .init(ascii: "9") }) - /// - /// // Attempt to convert to an `Int` - /// guard let int = Int(prefix) else { - /// struct ParseError: Error {} - /// throw ParseError() - /// } - /// - /// // Incrementally consume bytes from input - /// input.removeFirst(prefix.count) - /// - /// return int - /// } - /// } - /// - /// extension Digits: ParserPrinter where Input: PrependableCollection { - /// func print(_ output: Int, into input: inout Input) { - /// // Convert `Int` to string's underlying bytes - /// let bytes = String(output).utf8 - /// - /// // Prepend bytes using `PrependableCollection` conformance. - /// input.prepend(contentsOf: bytes) - /// } - /// } - /// ``` - /// - /// The `Digits` parser-printer now works on any collection of UTF-8 code units, including - /// `UTF8View` and `ArraySlice`: - /// - /// ```swift - /// var input = "123"[...].utf8 - /// try Digits().parse(&input) // 123 - /// try Digits().print(123, into: &input) - /// Substring(input) // "123" - /// ``` - /// - /// ```swift - /// var input = ArraySlice("123"[...].utf8) - /// try Digits().parse(&input) // 123 - /// try Digits().print(123, into: &input) - /// Substring(decoding: input, as: UTF8.self) // "123" - /// ``` - public protocol PrependableCollection: Collection, _EmptyInitializable { - /// Inserts the elements of a sequence or collection to the beginning of this collection. - /// - /// The collection being prepended to allocates any additional necessary storage to hold the new - /// elements. - /// - /// - Parameter newElements: The elements to append to the collection. - mutating func prepend(contentsOf newElements: S) where S.Element == Element - } -#else - public protocol PrependableCollection: Collection, _EmptyInitializable { - mutating func prepend(contentsOf newElements: S) where S.Element == Element - } -#endif +/// A collection that supports empty initialization and the ability to prepend a sequence of +/// elements of elements to itself. +/// +/// `PrependableCollection` is a specialized subset of `RangeReplaceableCollection` that is tuned +/// to incremental printing. +/// +/// In fact, any `RangeReplaceableCollection` can get a conformance for free: +/// +/// ```swift +/// extension MyRangeReplaceableCollection: PrependableCollection {} +/// ``` +/// +/// Because it is also less strict than `RangeReplaceableCollection`, it is an appropriate +/// protocol to conform to for types that cannot and should not conform to +/// `RangeReplaceableCollection` directly. +/// +/// For example, `Substring.UTF8View` is a common input for string parsers to parse from, but it +/// does not conform to `RangeReplaceableCollection`. It does, however, conform to +/// `PrependableCollection` by validating and prepending the given UTF-8 bytes to its underlying +/// substring. So in order to write a parser against generic sequences of UTF-8 bytes, you would +/// constrain its input against `PrependableCollection`. +/// +/// For example the following `Digits` parser is generic over an `Collection` of bytes, and its +/// printer conformance further constraints its input to be prependable. +/// +/// ```swift +/// struct Digits: Parser +/// where +/// Input.Element == UTF8.CodeUnit, // Required for working with a collection of bytes +/// Input.SubSequence == Input // Required for the parser to consume from input +/// { +/// func parse(_ input: inout Input) throws -> Int { +/// // Collect all bytes between ASCII "0" and "9" +/// let prefix = input.prefix(while: { $0 >= .init(ascii: "0") && $0 <= .init(ascii: "9") }) +/// +/// // Attempt to convert to an `Int` +/// guard let int = Int(prefix) else { +/// struct ParseError: Error {} +/// throw ParseError() +/// } +/// +/// // Incrementally consume bytes from input +/// input.removeFirst(prefix.count) +/// +/// return int +/// } +/// } +/// +/// extension Digits: ParserPrinter where Input: PrependableCollection { +/// func print(_ output: Int, into input: inout Input) { +/// // Convert `Int` to string's underlying bytes +/// let bytes = String(output).utf8 +/// +/// // Prepend bytes using `PrependableCollection` conformance. +/// input.prepend(contentsOf: bytes) +/// } +/// } +/// ``` +/// +/// The `Digits` parser-printer now works on any collection of UTF-8 code units, including +/// `UTF8View` and `ArraySlice`: +/// +/// ```swift +/// var input = "123"[...].utf8 +/// try Digits().parse(&input) // 123 +/// try Digits().print(123, into: &input) +/// Substring(input) // "123" +/// ``` +/// +/// ```swift +/// var input = ArraySlice("123"[...].utf8) +/// try Digits().parse(&input) // 123 +/// try Digits().print(123, into: &input) +/// Substring(decoding: input, as: UTF8.self) // "123" +/// ``` +public protocol PrependableCollection: Collection, _EmptyInitializable { + /// Inserts the elements of a sequence or collection to the beginning of this collection. + /// + /// The collection being prepended to allocates any additional necessary storage to hold the new + /// elements. + /// + /// - Parameter newElements: The elements to append to the collection. + mutating func prepend(contentsOf newElements: S) where S.Element == Element +} extension PrependableCollection { /// Creates a new instance of a collection containing the elements of a sequence. diff --git a/Sources/swift-parsing-benchmark/Arithmetic.swift b/Sources/swift-parsing-benchmark/Arithmetic.swift index b3ac07a72a..b24839f8c6 100644 --- a/Sources/swift-parsing-benchmark/Arithmetic.swift +++ b/Sources/swift-parsing-benchmark/Arithmetic.swift @@ -5,47 +5,44 @@ import Parsing /// This benchmark demonstrates how to parse a recursive grammar: arithmetic. let arithmeticSuite = BenchmarkSuite(name: "Arithmetic") { suite in struct AdditionAndSubtraction: Parser { - func parse(_ input: inout Substring.UTF8View) throws -> Double { - try InfixOperator(associativity: .left) { + var body: some Parser { + InfixOperator(associativity: .left) { OneOf { - "+".utf8.map { (+) } + "+".utf8.map { (+) as (Double, Double) -> Double } "-".utf8.map { (-) } } } lowerThan: { MultiplicationAndDivision() } - .parse(&input) } } struct MultiplicationAndDivision: Parser { - func parse(_ input: inout Substring.UTF8View) throws -> Double { - try InfixOperator(associativity: .left) { + var body: some Parser { + InfixOperator(associativity: .left) { OneOf { - "*".utf8.map { (*) } + "*".utf8.map { (*) as (Double, Double) -> Double } "/".utf8.map { (/) } } } lowerThan: { Exponent() } - .parse(&input) } } struct Exponent: Parser { - func parse(_ input: inout Substring.UTF8View) throws -> Double { - try InfixOperator(associativity: .left) { - "^".utf8.map { pow } + var body: some Parser { + InfixOperator(associativity: .left) { + "^".utf8.map { pow as (Double, Double) -> Double } } lowerThan: { Factor() } - .parse(&input) } } struct Factor: Parser { - func parse(_ input: inout Substring.UTF8View) throws -> Double { - try OneOf { + var body: some Parser { + OneOf { Parse { "(".utf8 AdditionAndSubtraction() @@ -54,7 +51,6 @@ let arithmeticSuite = BenchmarkSuite(name: "Arithmetic") { suite in Double.parser() } - .parse(&input) } } @@ -68,9 +64,10 @@ let arithmeticSuite = BenchmarkSuite(name: "Arithmetic") { suite in } } -public struct InfixOperator: Parser +public struct InfixOperator: Parser where - Operator.Input == Operand.Input, + Operator.Input == Input, + Operand.Input == Input, Operator.Output == (Operand.Output, Operand.Output) -> Operand.Output { public let `associativity`: Associativity @@ -80,8 +77,8 @@ where @inlinable public init( associativity: Associativity, - @ParserBuilder _ operator: () -> Operator, - @ParserBuilder lowerThan operand: () -> Operand // Should this be called `precedes operand:`? + @ParserBuilder _ operator: () -> Operator, + @ParserBuilder lowerThan operand: () -> Operand // Should this be called `precedes:`? ) { self.associativity = `associativity` self.operand = operand() @@ -89,7 +86,7 @@ where } @inlinable - public func parse(_ input: inout Operand.Input) rethrows -> Operand.Output { + public func parse(_ input: inout Input) rethrows -> Operand.Output { switch associativity { case .left: var lhs = try self.operand.parse(&input) diff --git a/Sources/swift-parsing-benchmark/BinaryData.swift b/Sources/swift-parsing-benchmark/BinaryData.swift index 20ba2128f3..d9119e848c 100644 --- a/Sources/swift-parsing-benchmark/BinaryData.swift +++ b/Sources/swift-parsing-benchmark/BinaryData.swift @@ -24,177 +24,178 @@ import Parsing /// | ARCOUNT | /// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ let binaryDataSuite = BenchmarkSuite(name: "BinaryData") { suite in - struct Word16Parser: Parser { - func parse(_ input: inout ArraySlice) throws -> UInt16 { - guard input.count >= 2 - else { - struct ParsingError: Error {} - throw ParsingError() + #if swift(>=5.8) + struct Word16Parser: Parser { + func parse(_ input: inout ArraySlice) throws -> UInt16 { + guard input.count >= 2 + else { + struct ParsingError: Error {} + throw ParsingError() + } + let output = UInt16(input[input.startIndex]) + UInt16(input[input.startIndex + 1]) << 8 + input.removeFirst(2) + return output } - let output = UInt16(input[input.startIndex]) + UInt16(input[input.startIndex + 1]) << 8 - input.removeFirst(2) - return output } - } - - let id = Word16Parser() - - let fields1 = First>().map { (byte: UInt8) in - ( - qr: Bit(rawValue: byte & 0b00000001)!, - opcode: Opcode(rawValue: (byte & 0b00011110) >> 1), - aa: Bit(rawValue: (byte & 0b00100000) >> 5)!, - tc: Bit(rawValue: (byte & 0b01000000) >> 6)!, - rd: Bit(rawValue: (byte & 0b10000000) >> 7)! - ) - } - - let fields2 = First>().map { byte in - ( - ra: Bit(rawValue: byte & 0b00000001)!, - z: UInt3(uint8: (byte & 0b00001110) >> 1)!, - rcode: Rcode(rawValue: (byte & 0b11110000) >> 4) - ) - } - - let counts = Parse { - (qd: $0, an: $1, ns: $2, ar: $3) - } with: { - Word16Parser() - Word16Parser() - Word16Parser() - Word16Parser() - } - - let header = Parse { id, fields1, fields2, counts in - DnsHeader( - id: id, - qr: fields1.qr, - opcode: fields1.opcode, - aa: fields1.aa, - tc: fields1.tc, - rd: fields1.rd, - ra: fields2.ra, - z: fields2.z, - rcode: fields2.rcode, - qdcount: counts.qd, - ancount: counts.an, - nscount: counts.ns, - arcount: counts.ar - ) - } with: { - id - fields1 - fields2 - counts - } - - let input: [UInt8] = [ - // header - 42, 142, - 0b10100011, 0b00110000, - 128, 0, - 100, 200, - 254, 1, - 128, 128, - - // rest of packet - 0xDE, 0xAD, 0xBE, 0xEF, - ] - var output: DnsHeader! - var rest: ArraySlice! - - suite.benchmark("Parser") { - var input = input[...] - output = try header.parse(&input) - rest = input - } tearDown: { - precondition( - output - == DnsHeader( - id: 36_394, - qr: .one, - opcode: .inverseQuery, - aa: .one, - tc: .zero, - rd: .one, - ra: .zero, - z: UInt3(uint8: 0)!, - rcode: .nameError, - qdcount: 128, - ancount: 51_300, - nscount: 510, - arcount: 32_896 - ) - ) - precondition(rest == [0xDE, 0xAD, 0xBE, 0xEF]) - } - - struct DnsHeader: Equatable { - let id: UInt16 - let qr: Bit - let opcode: Opcode - let aa: Bit - let tc: Bit - let rd: Bit - let ra: Bit - let z: UInt3 - let rcode: Rcode - let qdcount: UInt16 - let ancount: UInt16 - let nscount: UInt16 - let arcount: UInt16 - } - - enum Bit: Equatable { - case zero, one - - init?(rawValue: UInt8) { - if rawValue == 0 { - self = .zero - } else if rawValue == 1 { - self = .one - } else { - return nil + + struct DNSHeaderParser: Parser { + var body: some Parser, DNSHeader> { + Parse { id, fields1, fields2, counts in + DNSHeader( + id: id, + qr: fields1.qr, + opcode: fields1.opcode, + aa: fields1.aa, + tc: fields1.tc, + rd: fields1.rd, + ra: fields2.ra, + z: fields2.z, + rcode: fields2.rcode, + qdcount: counts.qd, + ancount: counts.an, + nscount: counts.ns, + arcount: counts.ar + ) + } with: { + Word16Parser() + + First().map { byte in + ( + qr: Bit(rawValue: byte & 0b00000001)!, + opcode: Opcode(rawValue: (byte & 0b00011110) >> 1), + aa: Bit(rawValue: (byte & 0b00100000) >> 5)!, + tc: Bit(rawValue: (byte & 0b01000000) >> 6)!, + rd: Bit(rawValue: (byte & 0b10000000) >> 7)! + ) + } + + First().map { byte in + ( + ra: Bit(rawValue: byte & 0b00000001)!, + z: UInt3(uint8: (byte & 0b00001110) >> 1)!, + rcode: Rcode(rawValue: (byte & 0b11110000) >> 4) + ) + } + + Parse { + (qd: $0, an: $1, ns: $2, ar: $3) + } with: { + Word16Parser() + Word16Parser() + Word16Parser() + Word16Parser() + } + } + } + } + + let input: [UInt8] = [ + // header + 42, 142, + 0b10100011, 0b00110000, + 128, 0, + 100, 200, + 254, 1, + 128, 128, + + // rest of packet + 0xDE, 0xAD, 0xBE, 0xEF, + ] + var output: DNSHeader! + var rest: ArraySlice! + + suite.benchmark("Parser") { + var input = input[...] + output = try DNSHeaderParser().parse(&input) + rest = input + } tearDown: { + precondition( + output + == DNSHeader( + id: 36_394, + qr: .one, + opcode: .inverseQuery, + aa: .one, + tc: .zero, + rd: .one, + ra: .zero, + z: UInt3(uint8: 0)!, + rcode: .nameError, + qdcount: 128, + ancount: 51_300, + nscount: 510, + arcount: 32_896 + ) + ) + precondition(rest == [0xDE, 0xAD, 0xBE, 0xEF]) + } + + struct DNSHeader: Equatable { + let id: UInt16 + let qr: Bit + let opcode: Opcode + let aa: Bit + let tc: Bit + let rd: Bit + let ra: Bit + let z: UInt3 + let rcode: Rcode + let qdcount: UInt16 + let ancount: UInt16 + let nscount: UInt16 + let arcount: UInt16 + } + + enum Bit: Equatable { + case zero, one + + init?(rawValue: UInt8) { + if rawValue == 0 { + self = .zero + } else if rawValue == 1 { + self = .one + } else { + return nil + } } } - } - - struct UInt3: Equatable { - let bit0: Bit - let bit1: Bit - let bit2: Bit - - init?(uint8: UInt8) { - guard - uint8 & 0b11111000 == 0, - let bit0 = Bit(rawValue: uint8 & 0b001), - let bit1 = Bit(rawValue: uint8 & 0b010), - let bit2 = Bit(rawValue: uint8 & 0b100) - else { return nil } - - self.bit0 = bit0 - self.bit1 = bit1 - self.bit2 = bit2 + + struct UInt3: Equatable { + let bit0: Bit + let bit1: Bit + let bit2: Bit + + init?(uint8: UInt8) { + guard + uint8 & 0b11111000 == 0, + let bit0 = Bit(rawValue: uint8 & 0b001), + let bit1 = Bit(rawValue: uint8 & 0b010), + let bit2 = Bit(rawValue: uint8 & 0b100) + else { return nil } + + self.bit0 = bit0 + self.bit1 = bit1 + self.bit2 = bit2 + } + } + + struct Rcode: Equatable, RawRepresentable { + let rawValue: UInt8 + + static let noError = Self(rawValue: 0) + static let formatError = Self(rawValue: 1) + static let serverFailure = Self(rawValue: 2) + static let nameError = Self(rawValue: 3) + static let notImplemented = Self(rawValue: 4) + static let refused = Self(rawValue: 5) + } + + struct Opcode: Equatable, RawRepresentable { + let rawValue: UInt8 + + static let standardQuery = Self(rawValue: 0) + static let inverseQuery = Self(rawValue: 1) + static let status = Self(rawValue: 2) } - } - - struct Rcode: Equatable, RawRepresentable { - let rawValue: UInt8 - - static let noError = Self(rawValue: 0) - static let formatError = Self(rawValue: 1) - static let serverFailure = Self(rawValue: 2) - static let nameError = Self(rawValue: 3) - static let notImplemented = Self(rawValue: 4) - static let refused = Self(rawValue: 5) - } - - struct Opcode: Equatable, RawRepresentable { - let rawValue: UInt8 - - static let standardQuery = Self(rawValue: 0) - static let inverseQuery = Self(rawValue: 1) - static let status = Self(rawValue: 2) - } + #endif } diff --git a/Sources/swift-parsing-benchmark/CSV.swift b/Sources/swift-parsing-benchmark/CSV.swift index 3a6a0c3b64..faa45763ad 100644 --- a/Sources/swift-parsing-benchmark/CSV.swift +++ b/Sources/swift-parsing-benchmark/CSV.swift @@ -2,41 +2,51 @@ import Benchmark import Foundation import Parsing -/// This benchmark demonstrates how to define a simple CSV parser with quoted fields and measures its -/// performance against more a more ad hoc approach at the same level of abstraction. +/// This benchmark demonstrates how to define a simple CSV parser with quoted fields and measures +/// its performance against more a more ad hoc approach at the same level of abstraction. let csvSuite = BenchmarkSuite(name: "CSV") { suite in - let plainField = Prefix { $0 != .init(ascii: ",") && $0 != .init(ascii: "\n") } + struct FieldParser: ParserPrinter { + var body: some ParserPrinter { + OneOf { + Parse { + "\"".utf8 + Prefix { $0 != UInt8(ascii: "\"") } + "\"".utf8 + } - let quotedField = ParsePrint { - "\"".utf8 - Prefix { $0 != .init(ascii: "\"") } - "\"".utf8 - } - - let field = OneOf { - quotedField - plainField + Prefix { $0 != UInt8(ascii: ",") && $0 != UInt8(ascii: "\n") } + } + .map(.string) + } } - .map(.string) - let line = Many { - field - } separator: { - ",".utf8 + struct LineParser: ParserPrinter { + var body: some ParserPrinter { + Many { + FieldParser() + } separator: { + ",".utf8 + } + } } - let csv = Many { - line - } separator: { - "\n".utf8 - } terminator: { - End() + struct CSVParser: ParserPrinter { + var body: some ParserPrinter { + Many { + LineParser() + } separator: { + "\n".utf8 + } terminator: { + End() + } + } } let expectedRowCount = 1_000 let expectedColumnCount = 5 var output: [[String]] = [] + let csv = CSVParser() suite.benchmark("Parser") { output = try csv.parse(csvInput) } tearDown: { diff --git a/Sources/swift-parsing-benchmark/Color.swift b/Sources/swift-parsing-benchmark/Color.swift index 53159736af..0a75b08374 100644 --- a/Sources/swift-parsing-benchmark/Color.swift +++ b/Sources/swift-parsing-benchmark/Color.swift @@ -26,11 +26,15 @@ let colorSuite = BenchmarkSuite(name: "Color") { suite in } } - let hexColor = ParsePrint(.memberwise(Color.init(red:green:blue:))) { - "#".utf8 - HexByte() - HexByte() - HexByte() + struct HexColor: ParserPrinter { + var body: some ParserPrinter { + ParsePrint(.memberwise(Color.init(red:green:blue:))) { + "#".utf8 + HexByte() + HexByte() + HexByte() + } + } } let input = "#FF0000" @@ -39,9 +43,9 @@ let colorSuite = BenchmarkSuite(name: "Color") { suite in suite.benchmark("Parser") { var input = input[...].utf8 - output = try hexColor.parse(&input) + output = try HexColor().parse(&input) } tearDown: { precondition(output == expected) - precondition(try! hexColor.print(output).elementsEqual("#ff0000".utf8) == true) + precondition(try! HexColor().print(output).elementsEqual("#ff0000".utf8) == true) } } diff --git a/Sources/swift-parsing-benchmark/Date.swift b/Sources/swift-parsing-benchmark/Date.swift index b96358da29..032888992e 100644 --- a/Sources/swift-parsing-benchmark/Date.swift +++ b/Sources/swift-parsing-benchmark/Date.swift @@ -9,108 +9,60 @@ import Parsing /// parse fractional seconds and time zone offsets automatically, and it will parse to the /// nanosecond, while the formatters do not parse beyond the millisecond. let dateSuite = BenchmarkSuite(name: "Date") { suite in - #if swift(>=5.7) - let timeDelim = OneOf { - "T".utf8 - "t".utf8 - " ".utf8 - } - - let nanoSecfrac = Prefix(while: (.init(ascii: "0") ... .init(ascii: "9")).contains) - .map { $0.prefix(9) } - - let timeSecfrac = Parse { - ".".utf8 - nanoSecfrac - } - .compactMap { n in - Int(String(decoding: n, as: UTF8.self)) - .map { $0 * Int(pow(10, 9 - Double(n.count))) } - } - - let timeNumoffset = Parse { - OneOf { - "+".utf8.map { 1 } - "-".utf8.map { -1 } + #if swift(>=5.8) + struct DateTime: Parser { + var body: some Parser { + Parse { year, month, day, hour, minute, second, nanosecond, timeZone in + DateComponents( + timeZone: timeZone, + year: year, + month: month, + day: day, + hour: hour, + minute: minute, + second: second, + nanosecond: nanosecond + ) + } with: { + Digits(4) + "-".utf8 + Digits(2) + "-".utf8 + Digits(2) + "T".utf8 + Digits(2) + ":".utf8 + Digits(2) + ":".utf8 + Digits(2) + Optionally { + ".".utf8 + Prefix(1...9, while: (UInt8(ascii: "0")...UInt8(ascii: "9")).contains) + .compactMap { n in Int(Substring(n)).map { $0 * Int(pow(10, 9 - Double(n.count))) } } + } + OneOf { + "Z".utf8.map { 0 } + Parse { + OneOf { + "+".utf8.map { 1 } + "-".utf8.map { -1 } + } + Digits(2).map { $0 * 60 } + ":".utf8 + Digits(2) + } + .map { $0 * ($1 + $2) } + } + .map { TimeZone(secondsFromGMT: $0) } + } } - Digits(2) - ":".utf8 - Digits(2) - } - - let timeOffset = OneOf { - "Z".utf8.map { ( /*sign: */1, /*minute: */ 0, /*second: */ 0) } - timeNumoffset - } - .compactMap { TimeZone(secondsFromGMT: $0 * ($1 * 60 + $2)) } - - let partialTime = Parse { - Digits(2) - ":".utf8 - Digits(2) - ":".utf8 - Digits(2) - Optionally { - timeSecfrac - } - } - - let fullDate = Parse { - Digits(4) - "-".utf8 - Digits(2) - "-".utf8 - Digits(2) - } - - let offsetDateTime = Parse { - fullDate - timeDelim - partialTime - timeOffset - } - .map { year, month, day, time, timeZone -> DateComponents in - let (hour, minute, second, nanosecond) = time - return DateComponents( - timeZone: timeZone, - year: year, month: month, day: day, - hour: hour, minute: minute, second: second, nanosecond: nanosecond - ) - } - - let localDateTime = Parse { - fullDate - timeDelim - partialTime - } - .map { year, month, day, time -> DateComponents in - let (hour, minute, second, nanosecond) = time - return DateComponents( - year: year, month: month, day: day, - hour: hour, minute: minute, second: second, nanosecond: nanosecond - ) - } - - let localDate = - fullDate - .map { DateComponents(year: $0, month: $1, day: $2) } - - let localTime = - partialTime - .map { DateComponents(hour: $0, minute: $1, second: $2, nanosecond: $3) } - - let dateTime = OneOf { - offsetDateTime - localDateTime - localDate - localTime } let input = "1979-05-27T00:32:00Z" let expected = Date(timeIntervalSince1970: 296_613_120) var output: Date! - let dateTimeParser = dateTime.compactMap(Calendar.current.date(from:)) + let dateTimeParser = DateTime().compactMap(Calendar.current.date(from:)) suite.benchmark("Parser") { var input = input[...].utf8 output = try dateTimeParser.parse(&input) diff --git a/Sources/swift-parsing-benchmark/HTTP.swift b/Sources/swift-parsing-benchmark/HTTP.swift index a37d0757f9..15ff16bf24 100644 --- a/Sources/swift-parsing-benchmark/HTTP.swift +++ b/Sources/swift-parsing-benchmark/HTTP.swift @@ -7,139 +7,124 @@ import Parsing /// /// In particular, it benchmarks the same HTTP header as that defined in `one_test`. let httpSuite = BenchmarkSuite(name: "HTTP") { suite in - let method = ParsePrint(.substring) { Prefix { $0.isToken } } - - let uri = ParsePrint(.substring) { Prefix { $0 != .init(ascii: " ") } } - - let httpVersion = ParsePrint(.substring) { - "HTTP/".utf8 - Prefix { $0.isVersion } - } - - let newline = OneOf { - "\r\n".utf8 - "\n".utf8 - } - - let requestLine = ParsePrint(.memberwise(Request.init(method:uri:version:))) { - method - " ".utf8 - uri - " ".utf8 - httpVersion - newline - } - - let headerValue = ParsePrint(.substring) { - Skip { - Prefix(1...) { $0.isHorizontalSpace } + #if swift(>=5.8) + struct RequestParser: ParserPrinter { + var body: some ParserPrinter { + let newline = OneOf { + "\r\n".utf8 + "\n".utf8 + } + let token = Prefix { $0.isToken }.map(.substring) + + ParsePrint(.memberwise(Request.init(method:uri:version:headers:))) { + token + " ".utf8 + ParsePrint(.substring) { Prefix { $0 != UInt8(ascii: " ") } } + " HTTP/".utf8 + Prefix { $0.isVersion }.map(.substring) + newline + Many(1...) { + ParsePrint(.memberwise(Header.init(name:value:))) { + token + ":".utf8 + Many(1...) { + Skip { Prefix(1...) { $0.isHorizontalWhitespace } }.printing(" ".utf8) + Prefix { !$0.isNewline }.map(.substring) + newline + } + } + } + } + } } - .printing(" ".utf8) - Prefix { !$0.isNewline } - newline - } - let header = ParsePrint(.memberwise(Header.init(name:value:))) { - Prefix { $0.isToken }.map(.substring) - ":".utf8 - Many { - headerValue - } - } - - let request = ParsePrint { - requestLine - Many { - header - } - } - - let input = """ - GET / HTTP/1.1 - Host: www.reddit.com - User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:15.0) Gecko/20100101 Firefox/15.0.1 - Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 - Accept-Language: en-us,en;q=0.5 - Accept-Encoding: gzip, deflate - Connection: keep-alive - - """ - let expected = ( - Request( + let input = """ + GET / HTTP/1.1 + Host: www.reddit.com + User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:15.0) Gecko/20100101 Firefox/15.0.1 + Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 + Accept-Language: en-us,en;q=0.5 + Accept-Encoding: gzip, deflate + Connection: keep-alive + + """ + let expected = Request( method: "GET", uri: "/", - version: "1.1" - ), - headers: [ - Header(name: "Host", value: ["www.reddit.com"]), - Header( - name: "User-Agent", - value: [ - "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:15.0) Gecko/20100101 Firefox/15.0.1" - ] - ), - Header( - name: "Accept", - value: ["text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"] - ), - Header(name: "Accept-Language", value: ["en-us,en;q=0.5"]), - Header(name: "Accept-Encoding", value: ["gzip, deflate"]), - Header(name: "Connection", value: ["keep-alive"]), - ] - ) - var output: (Request, [Header])! + version: "1.1", + headers: [ + Header(name: "Host", value: ["www.reddit.com"]), + Header( + name: "User-Agent", + value: [ + "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:15.0) Gecko/20100101 Firefox/15.0.1" + ] + ), + Header( + name: "Accept", + value: ["text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"] + ), + Header(name: "Accept-Language", value: ["en-us,en;q=0.5"]), + Header(name: "Accept-Encoding", value: ["gzip, deflate"]), + Header(name: "Connection", value: ["keep-alive"]), + ] + ) + var output: Request! + let parser = RequestParser() + + suite.benchmark("HTTP") { + var input = input[...].utf8 + output = try parser.parse(&input) + } tearDown: { + precondition(output == expected) + precondition(Substring(try! parser.print(output)) == input) + } + #endif +} - suite.benchmark("HTTP") { - var input = input[...].utf8 - output = try request.parse(&input) - } tearDown: { - precondition(output == expected) - precondition(Substring(try! request.print(output)) == input) - } +private struct Header: Equatable { + let name: Substring + let value: [Substring] } private struct Request: Equatable { let method: Substring let uri: Substring let version: Substring -} - -private struct Header: Equatable { - let name: Substring - let value: [Substring] + let headers: [Header] } extension UTF8.CodeUnit { - fileprivate var isHorizontalSpace: Bool { - self == .init(ascii: " ") || self == .init(ascii: "\t") + fileprivate var isHorizontalWhitespace: Bool { + self == Self(ascii: " ") || self == Self(ascii: "\t") } fileprivate var isNewline: Bool { - self == .init(ascii: "\n") || self == .init(ascii: "\r") + self == Self(ascii: "\n") || self == Self(ascii: "\r") } fileprivate var isToken: Bool { switch self { case 128..., ...31, - .init(ascii: "("), - .init(ascii: ")"), - .init(ascii: "<"), - .init(ascii: ">"), - .init(ascii: "@"), - .init(ascii: ","), - .init(ascii: ";"), - .init(ascii: ":"), - .init(ascii: "\\"), - .init(ascii: "'"), - .init(ascii: "/"), - .init(ascii: "["), - .init(ascii: "]"), - .init(ascii: "?"), - .init(ascii: "="), - .init(ascii: "{"), - .init(ascii: "}"), - .init(ascii: " "): + Self(ascii: "("), + Self(ascii: ")"), + Self(ascii: "<"), + Self(ascii: ">"), + Self(ascii: "@"), + Self(ascii: ","), + Self(ascii: ";"), + Self(ascii: ":"), + Self(ascii: "\\"), + Self(ascii: "'"), + Self(ascii: "/"), + Self(ascii: "["), + Self(ascii: "]"), + Self(ascii: "?"), + Self(ascii: "="), + Self(ascii: "{"), + Self(ascii: "}"), + Self(ascii: " "): return false default: return true @@ -147,6 +132,6 @@ extension UTF8.CodeUnit { } fileprivate var isVersion: Bool { - (.init(ascii: "0") ... .init(ascii: "9")).contains(self) || self == .init(ascii: ".") + (Self(ascii: "0")...Self(ascii: "9")).contains(self) || self == Self(ascii: ".") } } diff --git a/Sources/swift-parsing-benchmark/JSON.swift b/Sources/swift-parsing-benchmark/JSON.swift index cada26a249..18d4921d67 100644 --- a/Sources/swift-parsing-benchmark/JSON.swift +++ b/Sources/swift-parsing-benchmark/JSON.swift @@ -7,162 +7,168 @@ import Parsing /// It is mostly implemented according to the [spec](https://www.json.org/json-en.html) (we take a /// shortcut and use `Double.parser()`, which behaves accordingly). let jsonSuite = BenchmarkSuite(name: "JSON") { suite in - enum JSONValue: Equatable { - case array([Self]) - case boolean(Bool) - case null - case number(Double) - case object([String: Self]) - case string(String) - } - - var json: AnyParserPrinter! - - let unicode = ParsePrint(.unicode) { - Prefix(4) { $0.isHexDigit } - } - - let escape = Parse { - "\\".utf8 - - OneOf { - "\"".utf8.map { "\"" } - "\\".utf8.map { "\\" } - "/".utf8.map { "/" } - "b".utf8.map { "\u{8}" } - "f".utf8.map { "\u{c}" } - "n".utf8.map { "\n" } - "r".utf8.map { "\r" } - "t".utf8.map { "\t" } - unicode - } - } - - let string = ParsePrint { - "\"".utf8 - Many(into: "") { string, fragment in - string.append(contentsOf: fragment) - } decumulator: { string in - string.map(String.init).reversed().makeIterator() - } element: { - OneOf { - Prefix(1...) { $0.isUnescapedJSONStringByte }.map(.string) + #if swift(>=5.8) + struct JSONValue: ParserPrinter { + enum Output: Equatable { + case array([Self]) + case boolean(Bool) + case null + case number(Double) + case object([String: Self]) + case string(String) + } - escape + var body: some ParserPrinter { + Whitespace() + OneOf { + JSONObject().map(.case(Output.object)) + JSONArray().map(.case(Output.array)) + JSONString().map(.case(Output.string)) + Double.parser().map(.case(Output.number)) + Bool.parser().map(.case(Output.boolean)) + "null".utf8.map { Output.null } + } + Whitespace() } - } terminator: { - "\"".utf8 } - } - let object = ParsePrint { - "{".utf8 - Many(into: [String: JSONValue]()) { object, pair in - let (name, value) = pair - object[name] = value - } decumulator: { object in - (object.sorted(by: { $0.key < $1.key }) as [(String, JSONValue)]).reversed().makeIterator() - } element: { - Whitespace() - string - Whitespace() - ":".utf8 - Lazy { json! } - } separator: { - ",".utf8 - } terminator: { - "}".utf8 - } - } + struct JSONString: ParserPrinter { + var body: some ParserPrinter { + "\"".utf8 + Many(into: "") { string, fragment in + string.append(contentsOf: fragment) + } decumulator: { string in + string.map(String.init).reversed().makeIterator() + } element: { + OneOf { + Prefix(1) { $0.isUnescapedJSONStringByte }.map(.string) - let array = ParsePrint { - "[".utf8 - Many { - Lazy { json! } - } separator: { - ",".utf8 - } terminator: { - "]".utf8 + Parse { + "\\".utf8 + + OneOf { + "\"".utf8.map { "\"" } + "\\".utf8.map { "\\" } + "/".utf8.map { "/" } + "b".utf8.map { "\u{8}" } + "f".utf8.map { "\u{c}" } + "n".utf8.map { "\n" } + "r".utf8.map { "\r" } + "t".utf8.map { "\t" } + ParsePrint(.unicode) { + Prefix(4) { $0.isHexDigit } + } + } + } + } + } terminator: { + "\"".utf8 + } + } } - } - json = Parse { - Whitespace() - OneOf { - object.map(.case(JSONValue.object)) - array.map(.case(JSONValue.array)) - string.map(.case(JSONValue.string)) - Double.parser().map(.case(JSONValue.number)) - Bool.parser().map(.case(JSONValue.boolean)) - "null".utf8.map { JSONValue.null } + struct JSONObject: ParserPrinter { + var body: some ParserPrinter { + "{".utf8 + Many(into: [String: JSONValue.Output]()) { object, pair in + let (name, value) = pair + object[name] = value + } decumulator: { object in + (object.sorted(by: { $0.key < $1.key }) as [(String, JSONValue.Output)]) + .reversed() + .makeIterator() + } element: { + Whitespace() + JSONString() + Whitespace() + ":".utf8 + JSONValue() + } separator: { + ",".utf8 + } terminator: { + "}".utf8 + } + } } - Whitespace() - } - .eraseToAnyParserPrinter() - let input = #""" - { - "hello": true, - "goodbye": 42.42, - "whatever": null, - "xs": [1, "hello", null, false], - "ys": { - "0": 2, - "1": "goodbye\n" + struct JSONArray: ParserPrinter { + var body: some ParserPrinter { + "[".utf8 + Many { + JSONValue() + } separator: { + ",".utf8 + } terminator: { + "]".utf8 + } } } - """# - var jsonOutput: JSONValue! - suite.benchmark("Parser") { - var input = input[...].utf8 - jsonOutput = try json.parse(&input) - } tearDown: { - precondition( - jsonOutput - == .object([ - "hello": .boolean(true), - "goodbye": .number(42.42), - "whatever": .null, - "xs": .array([.number(1), .string("hello"), .null, .boolean(false)]), - "ys": .object([ - "0": .number(2), - "1": .string("goodbye\n"), - ]), - ]) - ) - // precondition( - // try! Substring(json.print(jsonOutput)) - // == """ - // {\ - // "goodbye":42.42,\ - // "hello":true,\ - // "whatever":null,\ - // "xs":[1.0,"hello",null,false],\ - // "ys":{"0":2.0,"1":"goodbye\\n"}\ - // } - // """ - // ) - // precondition(try! json.parse(json.print(jsonOutput)) == jsonOutput) - } - let dataInput = Data(input.utf8) - var objectOutput: Any! - suite.benchmark("JSONSerialization") { - objectOutput = try JSONSerialization.jsonObject(with: dataInput, options: []) - } tearDown: { - precondition( - (objectOutput as! NSDictionary) == [ + let json = JSONValue() + let input = #""" + { "hello": true, "goodbye": 42.42, - "whatever": NSNull(), - "xs": [1, "hello", nil, false], - "ys": [ + "whatever": null, + "xs": [1, "hello", null, false], + "ys": { "0": 2, - "1": "goodbye\n", - ], - ] - ) - } + "1": "goodbye\n" + } + } + """# + var jsonOutput: JSONValue.Output! + suite.benchmark("Parser") { + var input = input[...].utf8 + jsonOutput = try json.parse(&input) + } tearDown: { + precondition( + jsonOutput + == .object([ + "hello": .boolean(true), + "goodbye": .number(42.42), + "whatever": .null, + "xs": .array([.number(1), .string("hello"), .null, .boolean(false)]), + "ys": .object([ + "0": .number(2), + "1": .string("goodbye\n"), + ]), + ]) + ) + precondition( + try! Substring(json.print(jsonOutput)) + == """ + {\ + "goodbye":42.42,\ + "hello":true,\ + "whatever":null,\ + "xs":[1.0,"hello",null,false],\ + "ys":{"0":2.0,"1":"goodbye\\n"}\ + } + """ + ) + precondition(try! json.parse(json.print(jsonOutput)) == jsonOutput) + } + + let dataInput = Data(input.utf8) + var objectOutput: Any! + suite.benchmark("JSONSerialization") { + objectOutput = try JSONSerialization.jsonObject(with: dataInput, options: []) + } tearDown: { + precondition( + (objectOutput as! NSDictionary) == [ + "hello": true, + "goodbye": 42.42, + "whatever": NSNull(), + "xs": [1, "hello", nil, false] as [Any?], + "ys": [ + "0": 2, + "1": "goodbye\n", + ] as [String: Any], + ] + ) + } + #endif } extension UTF8.CodeUnit { diff --git a/Sources/swift-parsing-benchmark/Numerics.swift b/Sources/swift-parsing-benchmark/Numerics.swift index a135cc981c..b7c57daa23 100644 --- a/Sources/swift-parsing-benchmark/Numerics.swift +++ b/Sources/swift-parsing-benchmark/Numerics.swift @@ -47,14 +47,20 @@ let numericsSuite = BenchmarkSuite(name: "Numerics") { suite in let expected = Array(1...100_000) var output: [Int]! + struct IntsParser: Parser { + var body: some Parser { + Many { + Int.parser() + } separator: { + ",".utf8 + } + } + } + + let parser = IntsParser() suite.benchmark("Comma separated: Int.parser") { var input = input[...].utf8 - output = try Many { - Int.parser() - } separator: { - ",".utf8 - } - .parse(&input) + output = try parser.parse(&input) } tearDown: { precondition(output == expected) } @@ -120,14 +126,20 @@ let numericsSuite = BenchmarkSuite(name: "Numerics") { suite in let expected = (1...100_000).map(Double.init) var output: [Double]! + struct DoublesParser: Parser { + var body: some Parser { + Many { + Double.parser() + } separator: { + ",".utf8 + } + } + } + + let parser = DoublesParser() suite.benchmark("Comma separated: Double.parser") { var input = input[...].utf8 - output = try Many { - Double.parser() - } separator: { - ",".utf8 - } - .parse(&input) + output = try parser.parse(&input) } tearDown: { precondition(output == expected) } diff --git a/Sources/swift-parsing-benchmark/Race.swift b/Sources/swift-parsing-benchmark/Race.swift index b14dc7b91f..59be909026 100644 --- a/Sources/swift-parsing-benchmark/Race.swift +++ b/Sources/swift-parsing-benchmark/Race.swift @@ -6,192 +6,188 @@ import Parsing /// /// [parsing]: https://www.pointfree.co/collections/parsing let raceSuite = BenchmarkSuite(name: "Race") { suite in - struct Coordinate { - let latitude: Double - let longitude: Double - } - - enum Currency { case eur, gbp, usd } - - struct Money { - let currency: Currency - let dollars: Int - } - - struct Race { - let location: String - let entranceFee: Money - let difficulty: Int - let path: [Coordinate] - } - - let locationName = Prefix { $0 != .init(ascii: ",") }.map(.string) - - let currency = OneOf { - "€".utf8.map { Currency.eur } - "£".utf8.map { Currency.gbp } - "$".utf8.map { Currency.usd } - } - - let money = ParsePrint(.memberwise(Money.init(currency:dollars:))) { - currency - Int.parser() - } - - let difficulty = Many { "🥵".utf8 }.map(.count) - - let northSouthSign = OneOf { - "N".utf8.map { 1.0 } - "S".utf8.map { -1.0 } - } - - let eastWestSign = OneOf { - "E".utf8.map { 1.0 } - "W".utf8.map { -1.0 } - } - - let latitude = ParsePrint(.multiplySign) { - Double.parser() - "° ".utf8 - northSouthSign - } + #if swift(>=5.8) + struct Coordinate { + let latitude: Double + let longitude: Double + } - let longitude = ParsePrint(.multiplySign) { - Double.parser() - "° ".utf8 - eastWestSign - } + enum Currency { case eur, gbp, usd } - let zeroOrMoreSpaces = Skip { - Prefix { $0 == .init(ascii: " ") } - } - .printing(" ".utf8) + struct Money { + let currency: Currency + let dollars: Int + } - let coord = ParsePrint(.memberwise(Coordinate.init(latitude:longitude:))) { - latitude - Skip { - ",".utf8 - zeroOrMoreSpaces + struct Race { + let location: String + let entranceFee: Money + let difficulty: Int + let path: [Coordinate] } - longitude - } - let race = ParsePrint(.memberwise(Race.init)) { - ParsePrint { - locationName - Skip { - ",".utf8 - zeroOrMoreSpaces + struct SignParser: ParserPrinter { + let positive: String.UTF8View + let negative: String.UTF8View + + var body: some ParserPrinter { + ParsePrint(.multiplySign) { + Double.parser() + "° ".utf8 + OneOf { + self.positive.map { 1.0 } + self.negative.map { -1 } + } + } } } - ParsePrint { - money - Skip { - ",".utf8 - zeroOrMoreSpaces + + struct CoordinateParser: ParserPrinter { + var body: some ParserPrinter { + ParsePrint(.memberwise(Coordinate.init(latitude:longitude:))) { + SignParser(positive: "N".utf8, negative: "S".utf8) + Skip { + ",".utf8 + Whitespace(.horizontal).printing(" ".utf8) + } + SignParser(positive: "E".utf8, negative: "W".utf8) + } } } - ParsePrint { - difficulty - "\n".utf8 - } - Many { - coord - } separator: { - "\n".utf8 + + struct RaceParser: ParserPrinter { + var body: some ParserPrinter { + ParsePrint(.memberwise(Race.init(location:entranceFee:difficulty:path:))) { + Prefix { $0 != UInt8(ascii: ",") }.map(.string) + + Skip { + ",".utf8 + Whitespace(.horizontal).printing(" ".utf8) + } + + ParsePrint(.memberwise(Money.init(currency:dollars:))) { + OneOf { + "€".utf8.map { Currency.eur } + "£".utf8.map { .gbp } + "$".utf8.map { .usd } + } + Int.parser() + } + + Skip { + ",".utf8 + Whitespace(.horizontal).printing(" ".utf8) + } + + Many { "🥵".utf8 }.map(.count) + + "\n".utf8 + + Many { + CoordinateParser() + } separator: { + "\n".utf8 + } + } + } } - } - let races = Many { - race - } separator: { - "\n---\n".utf8 - } terminator: { - End() - } + struct RacesParser: ParserPrinter { + var body: some ParserPrinter { + Many { + RaceParser() + } separator: { + "\n---\n".utf8 + } terminator: { + End() + } + } + } - let input = """ - New York City, $300, 🥵🥵🥵🥵 - 40.60248° N, 74.06433° W - 40.61807° N, 74.02966° W - 40.64953° N, 74.00929° W - 40.67884° N, 73.98198° W - 40.69894° N, 73.95701° W - 40.72791° N, 73.95314° W - 40.74882° N, 73.94221° W - 40.7574° N, 73.95309° W - 40.76149° N, 73.96142° W - 40.77111° N, 73.95362° W - 40.8026° N, 73.93061° W - 40.80409° N, 73.92893° W - 40.81432° N, 73.93292° W - 40.80325° N, 73.94472° W - 40.77392° N, 73.96917° W - 40.77293° N, 73.97671° W - --- - Berlin, €100, 🥵🥵🥵 - 13.36015° N, 52.51516° E - 13.33999° N, 52.51381° E - 13.32539° N, 52.51797° E - 13.33696° N, 52.52507° E - 13.36454° N, 52.52278° E - 13.38152° N, 52.52295° E - 13.40072° N, 52.52969° E - 13.42555° N, 52.51508° E - 13.41858° N, 52.49862° E - 13.40929° N, 52.48882° E - 13.37968° N, 52.49247° E - 13.34898° N, 52.48942° E - 13.34103° N, 52.47626° E - 13.32851° N, 52.47122° E - 13.30852° N, 52.46797° E - 13.28742° N, 52.47214° E - 13.29091° N, 52.4827° E - 13.31084° N, 52.49275° E - 13.32052° N, 52.5019° E - 13.34577° N, 52.50134° E - 13.36903° N, 52.50701° E - 13.39155° N, 52.51046° E - 13.37256° N, 52.51598° E - --- - London, £500, 🥵🥵 - 51.48205° N, 0.04283° E - 51.47439° N, 0.0217° E - 51.47618° N, 0.02199° E - 51.49295° N, 0.05658° E - 51.47542° N, 0.03019° E - 51.47537° N, 0.03015° E - 51.47435° N, 0.03733° E - 51.47954° N, 0.04866° E - 51.48604° N, 0.06293° E - 51.49314° N, 0.06104° E - 51.49248° N, 0.0474° E - 51.48888° N, 0.03564° E - 51.48655° N, 0.0183° E - 51.48085° N, 0.02223° W - 51.4921° N, 0.0451° W - 51.49324° N, 0.04699° W - 51.50959° N, 0.05491° W - 51.50961° N, 0.0539° W - 51.4995° N, 0.01356° W - 51.50898° N, 0.02341° W - 51.51069° N, 0.04225° W - 51.51056° N, 0.04353° W - 51.50946° N, 0.0781° W - 51.51121° N, 0.09786° W - 51.50964° N, 0.1187° W - 51.50273° N, 0.1385° W - 51.50095° N, 0.12411° W - """ - var output: [Race]! - - suite.benchmark("Parser") { - var input = input[...].utf8 - output = try races.parse(&input) - } tearDown: { - precondition(output.count == 3) - precondition(try! races.print(output).elementsEqual(input.utf8) == true) - } + let input = """ + New York City, $300, 🥵🥵🥵🥵 + 40.60248° N, 74.06433° W + 40.61807° N, 74.02966° W + 40.64953° N, 74.00929° W + 40.67884° N, 73.98198° W + 40.69894° N, 73.95701° W + 40.72791° N, 73.95314° W + 40.74882° N, 73.94221° W + 40.7574° N, 73.95309° W + 40.76149° N, 73.96142° W + 40.77111° N, 73.95362° W + 40.8026° N, 73.93061° W + 40.80409° N, 73.92893° W + 40.81432° N, 73.93292° W + 40.80325° N, 73.94472° W + 40.77392° N, 73.96917° W + 40.77293° N, 73.97671° W + --- + Berlin, €100, 🥵🥵🥵 + 13.36015° N, 52.51516° E + 13.33999° N, 52.51381° E + 13.32539° N, 52.51797° E + 13.33696° N, 52.52507° E + 13.36454° N, 52.52278° E + 13.38152° N, 52.52295° E + 13.40072° N, 52.52969° E + 13.42555° N, 52.51508° E + 13.41858° N, 52.49862° E + 13.40929° N, 52.48882° E + 13.37968° N, 52.49247° E + 13.34898° N, 52.48942° E + 13.34103° N, 52.47626° E + 13.32851° N, 52.47122° E + 13.30852° N, 52.46797° E + 13.28742° N, 52.47214° E + 13.29091° N, 52.4827° E + 13.31084° N, 52.49275° E + 13.32052° N, 52.5019° E + 13.34577° N, 52.50134° E + 13.36903° N, 52.50701° E + 13.39155° N, 52.51046° E + 13.37256° N, 52.51598° E + --- + London, £500, 🥵🥵 + 51.48205° N, 0.04283° E + 51.47439° N, 0.0217° E + 51.47618° N, 0.02199° E + 51.49295° N, 0.05658° E + 51.47542° N, 0.03019° E + 51.47537° N, 0.03015° E + 51.47435° N, 0.03733° E + 51.47954° N, 0.04866° E + 51.48604° N, 0.06293° E + 51.49314° N, 0.06104° E + 51.49248° N, 0.0474° E + 51.48888° N, 0.03564° E + 51.48655° N, 0.0183° E + 51.48085° N, 0.02223° W + 51.4921° N, 0.0451° W + 51.49324° N, 0.04699° W + 51.50959° N, 0.05491° W + 51.50961° N, 0.0539° W + 51.4995° N, 0.01356° W + 51.50898° N, 0.02341° W + 51.51069° N, 0.04225° W + 51.51056° N, 0.04353° W + 51.50946° N, 0.0781° W + 51.51121° N, 0.09786° W + 51.50964° N, 0.1187° W + 51.50273° N, 0.1385° W + 51.50095° N, 0.12411° W + """ + var output: [Race]! + + let races = RacesParser() + suite.benchmark("Parser") { + var input = input[...].utf8 + output = try races.parse(&input) + } tearDown: { + precondition(output.count == 3) + precondition(try! races.print(output).elementsEqual(input.utf8) == true) + } + #endif } extension Conversion where Self == AnyConversion<(Double, Double), Double> { diff --git a/Sources/swift-parsing-benchmark/ReadmeExample.swift b/Sources/swift-parsing-benchmark/ReadmeExample.swift index 82ae802e4f..8ad044cfba 100644 --- a/Sources/swift-parsing-benchmark/ReadmeExample.swift +++ b/Sources/swift-parsing-benchmark/ReadmeExample.swift @@ -4,110 +4,132 @@ import Parsing /// This benchmark measures the performance of the examples given in the library's README. let readmeExampleSuite = BenchmarkSuite(name: "README Example") { suite in - let input = """ - 1,Blob,true - 2,Blob Jr.,false - 3,Blob Sr.,true - """ - let expectedOutput = [ - User(id: 1, name: "Blob", isAdmin: true), - User(id: 2, name: "Blob Jr.", isAdmin: false), - User(id: 3, name: "Blob Sr.", isAdmin: true), - ] - var output: [User]! + #if swift(>=5.8) + let input = """ + 1,Blob,true + 2,Blob Jr.,false + 3,Blob Sr.,true + """ + let expectedOutput = [ + User(id: 1, name: "Blob", isAdmin: true), + User(id: 2, name: "Blob Jr.", isAdmin: false), + User(id: 3, name: "Blob Sr.", isAdmin: true), + ] + var output: [User]! - struct User: Equatable { - var id: Int - var name: String - var isAdmin: Bool - } - - do { - let user = Parse(User.init(id:name:isAdmin:)) { - Int.parser() - "," - Prefix { $0 != "," }.map(String.init) - "," - Bool.parser() - } - let users = Many { - user - } separator: { - "\n" - } terminator: { - End() + struct User: Equatable { + var id: Int + var name: String + var isAdmin: Bool } - suite.benchmark("Parser: Substring") { - var input = input[...] - output = try users.parse(&input) - } tearDown: { - precondition(output == expectedOutput) - } - } + do { + struct UserParser: Parser { + var body: some Parser { + Parse(User.init(id:name:isAdmin:)) { + Int.parser() + "," + Prefix { $0 != "," }.map(String.init) + "," + Bool.parser() + } + } + } - do { - let user = Parse(User.init(id:name:isAdmin:)) { - Int.parser() - ",".utf8 - Prefix { $0 != .init(ascii: ",") }.map { String(Substring($0)) } - ",".utf8 - Bool.parser() - } - let users = Many { - user - } separator: { - "\n".utf8 - } terminator: { - End() - } + struct UsersParser: Parser { + var body: some Parser { + Many { + UserParser() + } separator: { + "\n" + } terminator: { + End() + } + } + } - suite.benchmark("Parser: UTF8") { - var input = input[...].utf8 - output = try users.parse(&input) - } tearDown: { - precondition(output == expectedOutput) + let users = UsersParser() + suite.benchmark("Parser: Substring") { + var input = input[...] + output = try users.parse(&input) + } tearDown: { + precondition(output == expectedOutput) + } } - } - - suite.benchmark("Ad hoc") { - output = - input - .split(separator: "\n") - .compactMap { row -> User? in - let fields = row.split(separator: ",") - guard - fields.count == 3, - let id = Int(fields[0]), - let isAdmin = Bool(String(fields[2])) - else { return nil } - return User(id: id, name: String(fields[1]), isAdmin: isAdmin) + do { + struct UserParser: Parser { + var body: some Parser { + Parse(User.init(id:name:isAdmin:)) { + Int.parser() + ",".utf8 + Prefix { $0 != UInt8(ascii: ",") }.map { String(Substring($0)) } + ",".utf8 + Bool.parser() + } + } } - } tearDown: { - precondition(output == expectedOutput) - } - if #available(macOS 10.15, *) { - let scanner = Scanner(string: input) - suite.benchmark("Scanner") { - output = [] - while scanner.currentIndex != input.endIndex { - guard - let id = scanner.scanInt(), - let _ = scanner.scanString(","), - let name = scanner.scanUpToString(","), - let _ = scanner.scanString(","), - let isAdmin = scanner.scanBool() - else { break } + struct UsersParser: Parser { + var body: some Parser { + Many { + UserParser() + } separator: { + "\n".utf8 + } terminator: { + End() + } + } + } - output.append(User(id: id, name: name, isAdmin: isAdmin)) - _ = scanner.scanString("\n") + let users = UsersParser() + suite.benchmark("Parser: UTF8") { + var input = input[...].utf8 + output = try users.parse(&input) + } tearDown: { + precondition(output == expectedOutput) } - } setUp: { - scanner.currentIndex = input.startIndex + } + + suite.benchmark("Ad hoc") { + output = + input + .split(separator: "\n") + .compactMap { row -> User? in + let fields = row.split(separator: ",") + guard + fields.count == 3, + let id = Int(fields[0]), + let isAdmin = Bool(String(fields[2])) + else { return nil } + + return User(id: id, name: String(fields[1]), isAdmin: isAdmin) + } } tearDown: { precondition(output == expectedOutput) } - } + + if #available(macOS 10.15, *) { + let scanner = Scanner(string: input) + suite.benchmark("Scanner") { + output = [] + while scanner.currentIndex != input.endIndex { + guard + let id = scanner.scanInt(), + let _ = scanner.scanString(","), + let name = scanner.scanUpToString(","), + let _ = scanner.scanString(","), + let isAdmin = scanner.scanBool() + else { break } + + output.append(User(id: id, name: name, isAdmin: isAdmin)) + _ = scanner.scanString("\n") + } + } setUp: { + scanner.currentIndex = input.startIndex + } tearDown: { + precondition(output == expectedOutput) + } + } + #endif } diff --git a/Sources/swift-parsing-benchmark/StringAbstractions.swift b/Sources/swift-parsing-benchmark/StringAbstractions.swift index a8a463149d..c73d1fea0b 100644 --- a/Sources/swift-parsing-benchmark/StringAbstractions.swift +++ b/Sources/swift-parsing-benchmark/StringAbstractions.swift @@ -22,21 +22,20 @@ let stringAbstractionsSuite = BenchmarkSuite(name: "String Abstractions") { suit var output: [Int]! suite.benchmark("Substring") { - var input = input[...].utf8 - output = try Many { - // NB: omitting `of: Substring.UTF8View.self` causes a segfault in Xcode 12.5.1 (Swift 5.4.1) - Int.parser(of: Substring.UTF8View.self) + let parser: some Parser = Many { + Int.parser() } separator: { From(.substring) { "\u{00E9}" } } - .parse(&input) + + var input = input[...].utf8 + output = try parser.parse(&input) } tearDown: { precondition(output.count == count) } suite.benchmark("UTF8") { - var input = input[...].utf8 - output = try Many { + let parser: some Parser = Many { Int.parser() } separator: { OneOf { @@ -44,7 +43,9 @@ let stringAbstractionsSuite = BenchmarkSuite(name: "String Abstractions") { suit "e\u{0301}".utf8 } } - .parse(&input) + + var input = input[...].utf8 + output = try parser.parse(&input) } tearDown: { precondition(output.count == count) } diff --git a/Sources/swift-parsing-benchmark/XCTestLogs.swift b/Sources/swift-parsing-benchmark/XCTestLogs.swift index cf2572f416..e5ded8c6cf 100644 --- a/Sources/swift-parsing-benchmark/XCTestLogs.swift +++ b/Sources/swift-parsing-benchmark/XCTestLogs.swift @@ -9,48 +9,58 @@ let xcodeLogsSuite = BenchmarkSuite(name: "Xcode Logs") { suite in suite.benchmark("Parser") { var input = xcodeLogs[...].utf8 - output = try testResultsUtf8.parse(&input) + output = try TestResults().parse(&input) } tearDown: { precondition(output.count == 284) } } -private let testCaseFinishedLine = Parse { - Skip { - PrefixThrough(" (".utf8) +private struct TestCaseFinishedLine: Parser { + var body: some Parser { + Skip { + PrefixThrough(" (".utf8) + } + Double.parser() + " seconds).\n".utf8 } - Double.parser() - " seconds).\n".utf8 } -private let testCaseStartedLine = Parse { - Skip { - PrefixUpTo("Test Case '-[".utf8) +private struct TestCaseStartedLine: Parser { + var body: some Parser { + Skip { + PrefixUpTo("Test Case '-[".utf8) + } + PrefixThrough("\n".utf8) + .map { line in line.split(separator: .init(ascii: " "))[3].dropLast(2) } + .map(Substring.init) } - PrefixThrough("\n".utf8) - .map { line in line.split(separator: .init(ascii: " "))[3].dropLast(2) } } -private let fileName = Parse { - "/".utf8 - PrefixThrough(".swift".utf8) - .compactMap { $0.split(separator: .init(ascii: "/")).last } +private struct FileName: Parser { + var body: some Parser { + "/".utf8 + PrefixThrough(".swift".utf8) + .compactMap { $0.split(separator: .init(ascii: "/")).last } + .map(Substring.init) + } } -private let testCaseBody = Parse { - fileName - ":".utf8 - Int.parser() - Skip { - PrefixThrough("] : ".utf8) +private struct _TestCaseBody: Parser { + var body: some Parser { + FileName() + ":".utf8 + Int.parser() + Skip { + PrefixThrough("] : ".utf8) + } + Rest().map(Substring.init) } - Rest() } struct TestCaseBody: Parser { func parse( _ input: inout Substring.UTF8View - ) throws -> (file: Substring.UTF8View, line: Int, message: Substring.UTF8View) { + ) throws -> (file: Substring, line: Int, message: Substring) { guard input.first == .init(ascii: "/") else { throw ParsingError() } @@ -71,7 +81,7 @@ struct TestCaseBody: Parser { .parse(&input) failure.removeLast() // trailing newline - let output = try testCaseBody.parse(&failure) + let output = try _TestCaseBody().parse(&failure) return output } catch { throw error @@ -90,36 +100,44 @@ enum TestResult { case passed(testName: Substring, time: Double) } -private let testFailed = Parse { - testCaseStartedLine - Many { TestCaseBody() } - testCaseFinishedLine -} -.map { testName, bodyData, time in - bodyData.map { body in - TestResult.failed( - failureMessage: Substring(body.2), - file: Substring(body.0), - line: body.1, - testName: Substring(testName), - time: time - ) +private struct TestFailed: Parser { + var body: some Parser { + Parse { testName, bodyData, time in + bodyData.map { body in + TestResult.failed( + failureMessage: body.2, + file: body.0, + line: body.1, + testName: testName, + time: time + ) + } + } with: { + TestCaseStartedLine() + Many(1...) { TestCaseBody() } + TestCaseFinishedLine() + } } } -.filter { !$0.isEmpty } -private let testPassed = Parse { - testCaseStartedLine.map(Substring.init) - testCaseFinishedLine -} -.map { [TestResult.passed(testName: $0, time: $1)] } - -private let testResult = OneOf { - testFailed - testPassed +private struct TestPassed: Parser { + var body: some Parser { + Parse { + [TestResult.passed(testName: $0, time: $1)] + } with: { + TestCaseStartedLine() + TestCaseFinishedLine() + } + } } -let testResultsUtf8 = Many { - testResult +private struct TestResults: Parser { + var body: some Parser { + Many(into: [TestResult](), +=) { + OneOf { + TestFailed() + TestPassed() + } + } + } } -.map { $0.flatMap { $0 } } diff --git a/Sources/variadics-generator/VariadicsGenerator.swift b/Sources/variadics-generator/VariadicsGenerator.swift deleted file mode 100644 index 2366202ed0..0000000000 --- a/Sources/variadics-generator/VariadicsGenerator.swift +++ /dev/null @@ -1,304 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2021 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -import ArgumentParser - -struct Permutation { - let arity: Int - // 1 -> - // 0 -> where P.Output == Void - let bits: Int64 - - func isCaptureless(at index: Int) -> Bool { - bits & (1 << (-index + arity - 1)) != 0 - } - - var hasCaptureless: Bool { - bits != 0 - } - - var identifier: String { - var result = "" - for i in 0.. Permutation? { - guard counter & (1 << arity) == 0 else { - return nil - } - defer { counter += 1 } - return Permutation(arity: arity, bits: counter) - } - } - - public func makeIterator() -> Iterator { - Iterator(arity: arity) - } -} - -func output(_ content: String) { - print(content, terminator: "") -} - -func outputForEach( - _ elements: C, separator: String, _ content: (C.Element) -> String -) { - for i in elements.indices { - output(content(elements[i])) - if elements.index(after: i) != elements.endIndex { - output(separator) - } - } -} - -struct VariadicsGenerator: ParsableCommand { - @Flag(help: "Generate `Zip's") - var generateZips = false - - @Flag(help: "Generate `OneOf's") - var generateOneOfs = false - - func run() throws { - output( - """ - // BEGIN AUTO-GENERATED CONTENT - - #if swift(<5.7) - - - """ - ) - - if self.generateZips { - for arity in 2...6 { - emitZipDeclarations(arity: arity) - } - } - - if self.generateOneOfs { - for arity in 3...10 { - emitOneOfDeclaration(arity: arity) - } - } - - output( - """ - #endif - - // END AUTO-GENERATED CONTENT - - """ - ) - } - - func emitZipDeclarations(arity: Int) { - for permutation in Permutations(arity: arity) { - // Emit type declaration. - let typeName = "Zip\(permutation.identifier)" - output("extension ParserBuilder {\n public struct \(typeName)<") - outputForEach(0..: Parser\n where\n ") - outputForEach(Array(zip(0.. P\(permutation.captureIndices[0]).Output ") - default: - output("-> (\n") - outputForEach(permutation.captureIndices, separator: ",\n") { " P\($0).Output" } - output("\n ) ") - } - output("{\n do {\n ") - outputForEach(0..(\n ") - outputForEach(0.. ParserBuilder.\(typeName)<") - outputForEach(0.. {\n") - output(" ParserBuilder.\(typeName)(") - outputForEach(0..: Parser\n where\n ") - outputForEach(Array(zip(0.. P0.Output {") - output("\n let original = input\n ") - outputForEach(0..(\n ") - outputForEach(0.. OneOfBuilder.\(typeName)<") - outputForEach(0.. {\n") - output(" OneOfBuilder.\(typeName)(") - outputForEach(0.. = Backtracking { + Prefix(2) { $0 == "A" } + } + var input = "AB"[...] - XCTAssertThrowsError( - try Backtracking { Prefix(2) { $0 == "A" } } - .parse(&input) - ) + XCTAssertThrowsError(try parser.parse(&input)) XCTAssertEqual("AB", Substring(input)) } func testSuccess() throws { + let parser: some Parser = Backtracking { + Prefix(1) { $0 == "A" } + } var input = "AB"[...] - let output = try Backtracking { Prefix(1) { $0 == "A" } } - .parse(&input) + let output = try parser.parse(&input) XCTAssertEqual("B", Substring(input)) XCTAssertEqual("A", output) } func testPrint() throws { - let input = try Backtracking { Prefix(2) { $0 == "A" } }.print("AA") + let parser: some ParserPrinter = Backtracking { + Prefix(2) { $0 == "A" } + } + + let input = try parser.print("AA"[...]) XCTAssertEqual(input, "AA") } } diff --git a/Tests/ParsingTests/BoolTests.swift b/Tests/ParsingTests/BoolTests.swift index 1e785d45f6..db4c72d518 100644 --- a/Tests/ParsingTests/BoolTests.swift +++ b/Tests/ParsingTests/BoolTests.swift @@ -32,13 +32,13 @@ final class BoolTests: XCTestCase { func testPrintsTrue() { var input = "!"[...] - XCTAssertNoThrow(try Bool.parser().print(true, into: &input)) + XCTAssertNoThrow(Bool.parser().print(true, into: &input.utf8)) XCTAssertEqual(input, "true!"[...]) } func testPrintsFalse() { var input = "!"[...] - XCTAssertNoThrow(try Bool.parser().print(false, into: &input)) + XCTAssertNoThrow(Bool.parser().print(false, into: &input.utf8)) XCTAssertEqual(input, "false!"[...]) } } diff --git a/Tests/ParsingTests/CaseIterableRawRepresentableTests.swift b/Tests/ParsingTests/CaseIterableRawRepresentableTests.swift index efdabdb712..0fe0b0e58c 100644 --- a/Tests/ParsingTests/CaseIterableRawRepresentableTests.swift +++ b/Tests/ParsingTests/CaseIterableRawRepresentableTests.swift @@ -8,14 +8,15 @@ final class CaseIterableRawRepresentableTests: XCTestCase { case blobJr = "Blob Jr" } - let peopleParser = Many { - Person.parser() - } separator: { - ",".utf8 - } terminator: { - End() + let peopleParser = Parse(input: Substring.UTF8View.self) { + Many { + Person.parser() + } separator: { + ",".utf8 + } terminator: { + End() + } } - var input = "Blob,Blob Jr"[...].utf8 XCTAssertEqual(try peopleParser.parse(&input), [.blob, .blobJr]) @@ -50,22 +51,26 @@ final class CaseIterableRawRepresentableTests: XCTestCase { case blobJr = 42 } - let peopleParser = Many { - Person.parser() - } separator: { - ",".utf8 - } terminator: { - End() + struct People: Parser { + var body: some Parser { + Many { + Person.parser() + } separator: { + ",".utf8 + } terminator: { + End() + } + } } var input = "4,42"[...].utf8 - XCTAssertEqual(try peopleParser.parse(&input), [.blob, .blobJr]) + XCTAssertEqual(try People().parse(&input), [.blob, .blobJr]) input = "42,4"[...].utf8 - XCTAssertEqual(try peopleParser.parse(&input), [.blobJr, .blob]) + XCTAssertEqual(try People().parse(&input), [.blobJr, .blob]) input = "42,100"[...].utf8 - XCTAssertThrowsError(try peopleParser.parse(&input)) { error in + XCTAssertThrowsError(try People().parse(&input)) { error in XCTAssertEqual( """ error: multiple failures occurred @@ -92,22 +97,26 @@ final class CaseIterableRawRepresentableTests: XCTestCase { case blobJr = -42 } - let peopleParser = Many { - Person.parser() - } separator: { - ",".utf8 - } terminator: { - End() + struct People: Parser { + var body: some Parser { + Many { + Person.parser() + } separator: { + ",".utf8 + } terminator: { + End() + } + } } var input = "-4,-42"[...].utf8 - XCTAssertEqual(try peopleParser.parse(&input), [.blob, .blobJr]) + XCTAssertEqual(try People().parse(&input), [.blob, .blobJr]) input = "-42,-4"[...].utf8 - XCTAssertEqual(try peopleParser.parse(&input), [.blobJr, .blob]) + XCTAssertEqual(try People().parse(&input), [.blobJr, .blob]) input = "-42,-100"[...].utf8 - XCTAssertThrowsError(try peopleParser.parse(&input)) { error in + XCTAssertThrowsError(try People().parse(&input)) { error in XCTAssertEqual( """ error: multiple failures occurred diff --git a/Tests/ParsingTests/CaseIterableTests.swift b/Tests/ParsingTests/CaseIterableTests.swift index 9b8130d8a4..572cec3cc0 100644 --- a/Tests/ParsingTests/CaseIterableTests.swift +++ b/Tests/ParsingTests/CaseIterableTests.swift @@ -8,22 +8,26 @@ final class CaseIterableTests: XCTestCase { case blobJr = "Blob Jr" } - let peopleParser = Many { - Person.parser() - } separator: { - ",".utf8 - } terminator: { - End() + struct People: Parser { + var body: some Parser { + Many { + Person.parser() + } separator: { + ",".utf8 + } terminator: { + End() + } + } } var input = "Blob,Blob Jr"[...].utf8 - XCTAssertEqual(try peopleParser.parse(&input), [.blob, .blobJr]) + XCTAssertEqual(try People().parse(&input), [.blob, .blobJr]) input = "Blob Jr,Blob"[...].utf8 - XCTAssertEqual(try peopleParser.parse(&input), [.blobJr, .blob]) + XCTAssertEqual(try People().parse(&input), [.blobJr, .blob]) input = "Blob,Mr Blob"[...].utf8 - XCTAssertThrowsError(try peopleParser.parse(&input)) { error in + XCTAssertThrowsError(try People().parse(&input)) { error in XCTAssertEqual( """ error: multiple failures occurred diff --git a/Tests/ParsingTests/ConditionalTests.swift b/Tests/ParsingTests/ConditionalTests.swift index b655c98561..4484c866ec 100644 --- a/Tests/ParsingTests/ConditionalTests.swift +++ b/Tests/ParsingTests/ConditionalTests.swift @@ -2,24 +2,28 @@ import Parsing import XCTest final class ConditionalTests: XCTestCase { - let parser = Int.parser() - .flatMap { n in - if n.isMultiple(of: 2) { - Always(true) - } else { - Fail(throwing: OddNumberError()) - } + struct MultipleOf2: Parser { + var body: some Parser { + Int.parser() + .flatMap { n in + if n.isMultiple(of: 2) { + Always(true) + } else { + Fail(throwing: OddNumberError()) + } + } } + } func testFirst() { var input = "42 Hello, world!"[...] - XCTAssertEqual(true, try parser.parse(&input)) + XCTAssertEqual(true, try MultipleOf2().parse(&input.utf8)) XCTAssertEqual(" Hello, world!", input) } func testSecond() { var input = "43 Hello, world!"[...] - XCTAssertThrowsError(try parser.parse(&input)) { error in + XCTAssertThrowsError(try MultipleOf2().parse(&input.utf8)) { error in XCTAssertEqual( """ error: OddNumberError() diff --git a/Tests/ParsingTests/ConsumedTests.swift b/Tests/ParsingTests/ConsumedTests.swift index 77522c1b4c..85b02b319e 100644 --- a/Tests/ParsingTests/ConsumedTests.swift +++ b/Tests/ParsingTests/ConsumedTests.swift @@ -3,10 +3,16 @@ import XCTest final class ConsumedTests: XCTestCase { func testConsumed() throws { + struct ConsumedWhitespace: Parser { + var body: some Parser { + Consumed { Whitespace() } + } + } + var input = " \r \t\t \r\n \n\r Hello, world!"[...].utf8 XCTAssertEqual( " \r \t\t \r\n \n\r ", - try Substring(Consumed { Whitespace() }.parse(&input)) + try Substring(ConsumedWhitespace().parse(&input)) ) XCTAssertEqual("Hello, world!", Substring(input)) diff --git a/Tests/ParsingTests/DigitsTests.swift b/Tests/ParsingTests/DigitsTests.swift index 060b9db41e..2cbc7fd41d 100644 --- a/Tests/ParsingTests/DigitsTests.swift +++ b/Tests/ParsingTests/DigitsTests.swift @@ -50,18 +50,22 @@ final class DigitsTests: XCTestCase { func testZeroMinimum() { struct Rational: Equatable { var numerator, denominator: Int } - let rational = Parse(.memberwise(Rational.init)) { - Digits(0...) - "." - Digits(1...) + struct RationalParser: ParserPrinter { + var body: some ParserPrinter { + Parse(.memberwise(Rational.init)) { + Digits(0...) + "." + Digits(1...) + } + } } XCTAssertEqual( - try rational.parse(".123"), + try RationalParser().parse(".123"), .init(numerator: 0, denominator: 123) ) XCTAssertEqual( - try rational.print(.init(numerator: 0, denominator: 123)), + try RationalParser().print(Rational(numerator: 0, denominator: 123)), ".123" ) } diff --git a/Tests/ParsingTests/FromSubstringTests.swift b/Tests/ParsingTests/FromSubstringTests.swift index d720d7a96b..a1bd95552e 100644 --- a/Tests/ParsingTests/FromSubstringTests.swift +++ b/Tests/ParsingTests/FromSubstringTests.swift @@ -3,7 +3,7 @@ import XCTest final class FromSubstringTests: XCTestCase { func testUTF8View() { - let p = Parse { + let p = Parse(input: Substring.UTF8View.self) { "caf".utf8 From(.substring) { "é" } } @@ -31,4 +31,34 @@ final class FromSubstringTests: XCTestCase { XCTAssertNoThrow(try p.parse(&input)) XCTAssert(input.isEmpty) } + + func testDeprecatedUTF8View() { + let p = Parse(input: Substring.UTF8View.self) { + "caf".utf8 + FromSubstring { "é" } + } + + var input = "caf\u{00E9}"[...].utf8 + XCTAssertNoThrow(try p.parse(&input)) + XCTAssert(input.isEmpty) + + input = "cafe\u{0301}"[...].utf8 + XCTAssertNoThrow(try p.parse(&input)) + XCTAssert(input.isEmpty) + } + + func testDeprecatedUnicodeScalarView() { + let p = Parse { + "caf".unicodeScalars + FromSubstring { "é" } + } + + var input = "caf\u{00E9}"[...].unicodeScalars + XCTAssertNoThrow(try p.parse(&input)) + XCTAssert(input.isEmpty) + + input = "cafe\u{0301}"[...].unicodeScalars + XCTAssertNoThrow(try p.parse(&input)) + XCTAssert(input.isEmpty) + } } diff --git a/Tests/ParsingTests/LazyTests.swift b/Tests/ParsingTests/LazyTests.swift index 5c9bc598be..d319623e48 100644 --- a/Tests/ParsingTests/LazyTests.swift +++ b/Tests/ParsingTests/LazyTests.swift @@ -6,7 +6,7 @@ final class LazyTests: XCTestCase { var input = "123 Hello"[...] var evaluated = 0 - let parser = Lazy> { + let parser = Lazy> { evaluated += 1 return Always(()) } diff --git a/Tests/ParsingTests/ManyTests.swift b/Tests/ParsingTests/ManyTests.swift index 2c0a3dac4d..61ad0dfdac 100644 --- a/Tests/ParsingTests/ManyTests.swift +++ b/Tests/ParsingTests/ManyTests.swift @@ -14,45 +14,60 @@ class ManyTests: XCTestCase { } func testSeparator() { + struct IntsParser: Parser { + var body: some Parser { + Many { + Int.parser() + } separator: { + ",".utf8 + } + } + } + var input = "1,2,3,4,5"[...].utf8 XCTAssertEqual( - try Many { - Int.parser() - } separator: { - ",".utf8 - } - .parse(&input), + try IntsParser().parse(&input), [1, 2, 3, 4, 5] ) XCTAssertEqual(Substring(input), "") } func testTrailingSeparator() { + struct IntsParser: Parser { + var body: some Parser { + Many { + Int.parser() + } separator: { + ",".utf8 + } + } + } + var input = "1,2,3,4,5,"[...].utf8 XCTAssertEqual( - try Many { - Int.parser() - } separator: { - ",".utf8 - } - .parse(&input), + try IntsParser().parse(&input), [1, 2, 3, 4, 5] ) XCTAssertEqual(Substring(input), ",") } func testMinimum() { + struct SixOrMoreInts: ParserPrinter { + var body: some ParserPrinter { + Many(6...) { + Int.parser() + } separator: { + ",".utf8 + } + } + } + var input = "1,2,3,4,5"[...].utf8 XCTAssertThrowsError( - try Many(6...) { - Int.parser() - } separator: { - ",".utf8 - } - .parse(&input) + try SixOrMoreInts().parse(&input) ) { error in XCTAssertEqual( """ @@ -67,12 +82,7 @@ class ManyTests: XCTestCase { XCTAssertEqual(Substring(input), "") XCTAssertThrowsError( - try Many(6...) { - Int.parser() - } separator: { - ",".utf8 - } - .print([1, 2, 3, 4, 5]) + try SixOrMoreInts().print([1, 2, 3, 4, 5]) ) { error in XCTAssertEqual( """ @@ -84,40 +94,45 @@ class ManyTests: XCTestCase { ) } + struct FiveOrMoreInts: Parser { + var body: some Parser { + Many(5...) { + Int.parser() + } separator: { + ",".utf8 + } + } + } + input = "1,2,3,4,5"[...].utf8 XCTAssertEqual( - try Many(5...) { - Int.parser() - } separator: { - ",".utf8 - } - .parse(&input), + try FiveOrMoreInts().parse(&input), [1, 2, 3, 4, 5] ) XCTAssertEqual(Substring(input), "") } func testMaximum() { + struct AtMostThreeInts: ParserPrinter { + var body: some ParserPrinter { + Many(...3) { + Int.parser() + } separator: { + ",".utf8 + } + } + } + var input = "1,2,3,4,5"[...].utf8 XCTAssertEqual( - try Many(...3) { - Int.parser() - } separator: { - ",".utf8 - } - .parse(&input), + try AtMostThreeInts().parse(&input), [1, 2, 3] ) XCTAssertEqual(Substring(input), ",4,5") XCTAssertThrowsError( - try Many(...3) { - Int.parser() - } separator: { - ",".utf8 - } - .print([1, 2, 3, 4, 5]) + try AtMostThreeInts().print([1, 2, 3, 4, 5]) ) { error in XCTAssertEqual( """ @@ -132,29 +147,39 @@ class ManyTests: XCTestCase { } func testReduce() { + struct SumParser: Parser { + var body: some Parser { + Many(into: 0, +=) { + Int.parser() + } separator: { + ",".utf8 + } + } + } + var input = "1,2,3,4,5"[...].utf8 XCTAssertEqual( - try Many(into: 0, +=) { - Int.parser() - } separator: { - ",".utf8 - } - .parse(&input), + try SumParser().parse(&input), 15 ) XCTAssertEqual(Substring(input), "") } func testEmptyComponents() { + struct MACAddressParser: Parser { + var body: some Parser { + Many { + Prefix(while: \.isHexDigit) + } separator: { + ":" + } + } + } + var input = "2001:db8::2:1"[...] XCTAssertEqual( - try Many { - Prefix(while: \.isHexDigit) - } separator: { - ":" - } - .parse(&input), + try MACAddressParser().parse(&input), ["2001", "db8", "", "2", "1"] ) } @@ -166,20 +191,28 @@ class ManyTests: XCTestCase { var isAdmin: Bool } - let user = Parse(User.init) { - Int.parser() - "," - Prefix { $0 != "," }.map(String.init) - "," - Bool.parser() + struct UserParser: Parser { + var body: some Parser { + Parse(input: Substring.self, User.init) { + Int.parser() + "," + Prefix { $0 != "," }.map(String.init) + "," + Bool.parser() + } + } } - let users = Many { - user - } separator: { - "\n" - } terminator: { - End() + struct UsersParser: Parser { + var body: some Parser { + Many { + UserParser() + } separator: { + "\n" + } terminator: { + End() + } + } } var input = """ @@ -193,7 +226,7 @@ class ManyTests: XCTestCase { User(id: 2, name: "Blob Sr", isAdmin: false), User(id: 3, name: "Blob Jr", isAdmin: true), ], - try users.parse(&input) + try UsersParser().parse(&input) ) input = """ @@ -201,7 +234,7 @@ class ManyTests: XCTestCase { 2,Blob Sr,false 3,Blob Jr,tru """ - XCTAssertThrowsError(try users.parse(&input)) { error in + XCTAssertThrowsError(try UsersParser().parse(&input)) { error in XCTAssertEqual( """ error: multiple failures occurred @@ -222,16 +255,20 @@ class ManyTests: XCTestCase { } func testTerminatorFails() { - let intsParser = Many { - Int.parser() - } separator: { - "," - } terminator: { - "---" + struct IntsParser: Parser { + var body: some Parser { + Many { + Int.parser() + } separator: { + "," + } terminator: { + "---" + } + } } var input = "1,2,3-"[...] - XCTAssertThrowsError(try intsParser.parse(&input)) { error in + XCTAssertThrowsError(try IntsParser().parse(&input)) { error in XCTAssertEqual( """ error: unexpected input @@ -246,7 +283,13 @@ class ManyTests: XCTestCase { } func testInfiniteLoop() { - XCTAssertThrowsError(try Many { Prefix(while: \.isNumber) }.parse("Hello world!")) { error in + struct ParserWithInfiniteLoop: Parser { + var body: some Parser { + Many { Prefix(while: \.isNumber) } + } + } + + XCTAssertThrowsError(try ParserWithInfiniteLoop().parse("Hello world!")) { error in XCTAssertEqual( """ error: infinite loop @@ -260,7 +303,7 @@ class ManyTests: XCTestCase { } func testThrowingAccumulator() { - let parser = Many(into: [Int]()) { (xs, x) throws in + let parser: some Parser = Many(into: [Int]()) { (xs, x) throws in struct UniqueIntegerError: Error {} guard !xs.contains(x) else { throw UniqueIntegerError() } diff --git a/Tests/ParsingTests/OneOfTests.swift b/Tests/ParsingTests/OneOfTests.swift index 55a7f91849..b0d829a53b 100644 --- a/Tests/ParsingTests/OneOfTests.swift +++ b/Tests/ParsingTests/OneOfTests.swift @@ -5,7 +5,7 @@ final class OneOfTests: XCTestCase { func testOneOfSingleton() { var input = "AB"[...] XCTAssertThrowsError( - try OneOf { Prefix(2) { $0 == "A" } } + try Parse(input: Substring.self) { OneOf { Prefix(2) { $0 == "A" } } } .parse(&input) ) XCTAssertEqual("B", Substring(input)) @@ -147,12 +147,17 @@ final class OneOfTests: XCTestCase { } func testRanking() { - XCTAssertThrowsError( - try OneOf { - Int.parser() - Prefix(2).compactMap { _ in Int?.none } + struct IntParser: Parser { + var body: some Parser { + OneOf { + Int.parser() + Prefix(2).compactMap { _ in Int?.none } + } } - .parse("Hello"[...].utf8) + } + + XCTAssertThrowsError( + try IntParser().parse("Hello"[...].utf8) ) { error in XCTAssertEqual( """ @@ -175,9 +180,11 @@ final class OneOfTests: XCTestCase { func testRanking_2() { XCTAssertThrowsError( - try OneOf { - Int.parser() - Prefix(2).compactMap { _ in Int?.none } + try Parse(input: Substring.UTF8View.self) { + OneOf { + Int.parser() + Prefix(2).compactMap { _ in Int?.none } + } } .parse("Hello") ) { error in @@ -200,165 +207,171 @@ final class OneOfTests: XCTestCase { } } - // func testJSON() { - // enum JSONValue: Equatable { - // case array([Self]) - // case boolean(Bool) - // case null - // case number(Double) - // case object([String: Self]) - // case string(String) - // } - // - // var json: AnyParserPrinter! - // - // let string = ParsePrint { - // "\"".utf8 - // Many(into: "") { string, fragment in - // string.append(contentsOf: fragment) - // } iterator: { string in - // string.map(String.init).reversed().makeIterator() - // } element: { - // OneOf { - // Prefix(1...) { - // $0 != .init(ascii: "\"") && $0 != .init(ascii: "\\") && $0 >= .init(ascii: " ") - // } - // .map(.string) - // - // Parse { - // "\\".utf8 - // - // OneOf { - // "\"".utf8.map { "\"" } - // "\\".utf8.map { "\\" } - // "/".utf8.map { "/" } - // "b".utf8.map { "\u{8}" } - // "f".utf8.map { "\u{c}" } - // "n".utf8.map { "\n" } - // "r".utf8.map { "\r" } - // "t".utf8.map { "\t" } - // - // Prefix(4) { $0.isHexDigit }.map(.unicode) - // } - // } - // } - // } terminator: { - // "\"".utf8 - // } - // } - // - // let object = ParsePrint { - // "{".utf8 - // Many(into: [String: JSONValue]()) { object, pair in - // let (name, value) = pair - // object[name] = value - // } iterator: { object in - // (object.sorted(by: { $0.key < $1.key }) as [(String, JSONValue)]).reversed().makeIterator() - // } element: { - // Whitespace() - // string - // Whitespace() - // ":".utf8 - // Lazy { json! } - // } separator: { - // ",".utf8 - // } terminator: { - // "}".utf8 - // } - // } - // - // let array = ParsePrint { - // "[".utf8 - // Many { - // Lazy { json! } - // } separator: { - // ",".utf8 - // } terminator: { - // "]".utf8 - // } - // } - // - // json = .init( - // ParsePrint { - // Whitespace() - // OneOf { - // object.map(.case(JSONValue.object)) - // array.map(.case(JSONValue.array)) - // string.map(.case(JSONValue.string)) - // Double.parser().map(.case(JSONValue.number)) - // Bool.parser().map(.case(JSONValue.boolean)) - // "null".utf8.map { JSONValue.null } - // } - // Whitespace() - // } - // ) - // - // let input = #""" - // { - // "hello": true, - // "goodbye": 42.42, - // "whatever": null, - // "xs": [1, "hello, null, false], - // "ys": { - // "0": 2, - // "1": "goodbye" - // } - // } - // """# - // - // XCTAssertThrowsError(try json.parse(input)) { error in - // XCTAssertEqual( - // #""" - // error: multiple failures occurred - // - // error: unexpected input - // --> input:5:34 - // 5 | …hello, null, false], - // | ^ expected 1 element satisfying predicate - // | ^ expected "\\" - // | ^ expected "\"" - // - // error: unexpected input - // --> input:5:13 - // 5 | "xs": [1, "hello, null, false], - // | ^ expected "{" - // | ^ expected "[" - // | ^ expected double - // | ^ expected "true" or "false" - // | ^ expected "null" - // - // error: unexpected input - // --> input:5:11 - // 5 | "xs": [1, "hello, null, false], - // | ^ expected "]" - // - // error: unexpected input - // --> input:5:9 - // 5 | "xs": [1, "hello, null, false], - // | ^ expected "{" - // | ^ expected "\"" - // | ^ expected double - // | ^ expected "true" or "false" - // | ^ expected "null" - // - // error: unexpected input - // --> input:4:19 - // 4 | "whatever": null, - // | ^ expected "}" - // - // error: unexpected input - // --> input:1:1 - // 1 | { - // | ^ expected "[" - // | ^ expected "\"" - // | ^ expected double - // | ^ expected "true" or "false" - // | ^ expected "null" - // """#, - // "\(error)" - // ) - // } - // } + #if swift(>=5.8) + func testJSON() { + struct JSONValue: ParserPrinter { + enum Output: Equatable { + case array([Self]) + case boolean(Bool) + case null + case number(Double) + case object([String: Self]) + case string(String) + } + + var body: some ParserPrinter { + Whitespace() + OneOf { + JSONObject().map(.case(Output.object)) + JSONArray().map(.case(Output.array)) + JSONString().map(.case(Output.string)) + Double.parser().map(.case(Output.number)) + Bool.parser().map(.case(Output.boolean)) + "null".utf8.map { Output.null } + } + Whitespace() + } + } + + struct JSONString: ParserPrinter { + var body: some ParserPrinter { + "\"".utf8 + Many(into: "") { string, fragment in + string.append(contentsOf: fragment) + } decumulator: { string in + string.map(String.init).reversed().makeIterator() + } element: { + OneOf { + Prefix(1) { $0.isUnescapedJSONStringByte }.map(.string) + + Parse { + "\\".utf8 + + OneOf { + "\"".utf8.map { "\"" } + "\\".utf8.map { "\\" } + "/".utf8.map { "/" } + "b".utf8.map { "\u{8}" } + "f".utf8.map { "\u{c}" } + "n".utf8.map { "\n" } + "r".utf8.map { "\r" } + "t".utf8.map { "\t" } + ParsePrint(.unicode) { + Prefix(4) { $0.isHexDigit } + } + } + } + } + } terminator: { + "\"".utf8 + } + } + } + + struct JSONObject: ParserPrinter { + var body: some ParserPrinter { + "{".utf8 + Many(into: [String: JSONValue.Output]()) { object, pair in + let (name, value) = pair + object[name] = value + } decumulator: { object in + (object.sorted(by: { $0.key < $1.key }) as [(String, JSONValue.Output)]) + .reversed() + .makeIterator() + } element: { + Whitespace() + JSONString() + Whitespace() + ":".utf8 + JSONValue() + } separator: { + ",".utf8 + } terminator: { + "}".utf8 + } + } + } + + struct JSONArray: ParserPrinter { + var body: some ParserPrinter { + "[".utf8 + Many { + JSONValue() + } separator: { + ",".utf8 + } terminator: { + "]".utf8 + } + } + } + + let input = #""" + { + "hello": true, + "goodbye": 42.42, + "whatever": null, + "xs": [1, "hello, null, false], + "ys": { + "0": 2, + "1": "goodbye" + } + } + """# + + XCTAssertThrowsError(try JSONValue().parse(input)) { error in + XCTAssertEqual( + #""" + error: multiple failures occurred + + error: unexpected input + --> input:5:34 + 5 | …hello, null, false], + | ^ expected 1 element satisfying predicate + | ^ expected "\\" + | ^ expected "\"" + + error: unexpected input + --> input:5:13 + 5 | "xs": [1, "hello, null, false], + | ^ expected "{" + | ^ expected "[" + | ^ expected double + | ^ expected "true" or "false" + | ^ expected "null" + + error: unexpected input + --> input:5:11 + 5 | "xs": [1, "hello, null, false], + | ^ expected "]" + + error: unexpected input + --> input:5:9 + 5 | "xs": [1, "hello, null, false], + | ^ expected "{" + | ^ expected "\"" + | ^ expected double + | ^ expected "true" or "false" + | ^ expected "null" + + error: unexpected input + --> input:4:19 + 4 | "whatever": null, + | ^ expected "}" + + error: unexpected input + --> input:1:1 + 1 | { + | ^ expected "[" + | ^ expected "\"" + | ^ expected double + | ^ expected "true" or "false" + | ^ expected "null" + """#, + "\(error)" + ) + } + } + #endif } extension UTF8.CodeUnit { @@ -367,6 +380,10 @@ extension UTF8.CodeUnit { || (.init(ascii: "A") ... .init(ascii: "F")).contains(self) || (.init(ascii: "a") ... .init(ascii: "f")).contains(self) } + + fileprivate var isUnescapedJSONStringByte: Bool { + self != .init(ascii: "\"") && self != .init(ascii: "\\") && self >= .init(ascii: " ") + } } extension Conversion where Self == AnyConversion { diff --git a/Tests/ParsingTests/OptionallyTests.swift b/Tests/ParsingTests/OptionallyTests.swift index e4cb516b8c..11532b542b 100644 --- a/Tests/ParsingTests/OptionallyTests.swift +++ b/Tests/ParsingTests/OptionallyTests.swift @@ -2,15 +2,21 @@ import Parsing import XCTest final class OptionalTests: XCTestCase { + struct OptionalBool: ParserPrinter { + var body: some ParserPrinter { + Optionally { Bool.parser() } + } + } + func testParseWrappedSuccess() { var input = "true Hello, world!"[...].utf8 - XCTAssertEqual(.some(true), Optionally { Bool.parser() }.parse(&input)) + XCTAssertEqual(.some(true), try OptionalBool().parse(&input)) XCTAssertEqual(" Hello, world!", Substring(input)) } func testParseWrappedFailure() { var input = "Hello, world!"[...].utf8 - XCTAssertEqual(.none, Optionally { Bool.parser() }.parse(&input)) + XCTAssertEqual(.none, try OptionalBool().parse(&input)) XCTAssertEqual("Hello, world!", Substring(input)) } @@ -31,22 +37,28 @@ final class OptionalTests: XCTestCase { func testPrintNilSuccess() { var input = "!"[...] - XCTAssertNoThrow(try Optionally { Bool.parser() }.print(.none, into: &input)) + XCTAssertNoThrow(try OptionalBool().print(.none, into: &input.utf8)) XCTAssertEqual("!"[...], input) } func testPrintValueSuccess() { var input = "!"[...] - XCTAssertNoThrow(try Optionally { Bool.parser() }.print(.some(true), into: &input)) + XCTAssertNoThrow(try OptionalBool().print(.some(true), into: &input.utf8)) XCTAssertEqual("true!"[...], input) } func testPrintBadOptionalValue() { + struct OptionalPrefix: ParserPrinter { + var body: some ParserPrinter { + Optionally { Prefix { !$0.isWhitespace } } + } + } + var input = "!"[...] XCTAssertThrowsError( - try Optionally { Prefix { !$0.isWhitespace } }.print("foo bar", into: &input)) + try OptionalPrefix().print("foo bar", into: &input)) XCTAssertEqual("!"[...], input) } } diff --git a/Tests/ParsingTests/ParseableFormatTests.swift b/Tests/ParsingTests/ParseableFormatTests.swift index aa75faa7a6..a3c2aa73c2 100644 --- a/Tests/ParsingTests/ParseableFormatTests.swift +++ b/Tests/ParsingTests/ParseableFormatTests.swift @@ -1,4 +1,4 @@ -#if swift(>=5.7) && (os(iOS) || os(macOS) || os(tvOS) || os(watchOS)) +#if os(iOS) || os(tvOS) || os(watchOS) import Parsing import XCTest diff --git a/Tests/ParsingTests/ParserBuilderTests.swift b/Tests/ParsingTests/ParserBuilderTests.swift index 4de6d5e50a..4cbb5b6012 100644 --- a/Tests/ParsingTests/ParserBuilderTests.swift +++ b/Tests/ParsingTests/ParserBuilderTests.swift @@ -4,7 +4,7 @@ import XCTest final class ParserBuilderTests: XCTestCase { func testBuildIfVoid() { var parseComma = true - var parser = Parse { + var parser = Parse(input: Substring.self) { "Hello" if parseComma { "," @@ -62,7 +62,7 @@ final class ParserBuilderTests: XCTestCase { func testBuildIfOutput() throws { var parseInt = true - var parser = Parse { + var parser = Parse(input: Substring.self) { if parseInt { Int.parser() " " @@ -118,7 +118,7 @@ final class ParserBuilderTests: XCTestCase { var input = "123 Blob"[...] XCTAssertThrowsError( - try Parse { + try Parse(input: Substring.self) { Int.parser() MyParser() } @@ -137,7 +137,8 @@ final class ParserBuilderTests: XCTestCase { XCTAssertEqual(input, " Blob"[...]) input = "123 Blob"[...] - func custom

(@ParserBuilder _ build: () -> P) -> P { + + func custom

(@ParserBuilder _ build: () -> P) -> P { build() } XCTAssertThrowsError( diff --git a/Tests/ParsingTests/ParsingErrorTests.swift b/Tests/ParsingTests/ParsingErrorTests.swift index f6b4536089..a929dc0aa3 100644 --- a/Tests/ParsingTests/ParsingErrorTests.swift +++ b/Tests/ParsingTests/ParsingErrorTests.swift @@ -100,13 +100,14 @@ class ParsingErrorTests: XCTestCase { } func testComplexStringLiteralParserError() { - let stringLiteral = Parse { + let asciiByte = Prefix(1...) { $0 != "\"" && $0 >= " " }.map(String.init) + let stringLiteral = Parse(input: Substring.self) { "\"" Many(into: "") { $0.append(contentsOf: $1) } element: { OneOf { - Prefix(1...) { $0 != "\"" && $0 >= " " }.map(String.init) + asciiByte Parse { "\\" OneOf { diff --git a/Tests/ParsingTests/PeekTests.swift b/Tests/ParsingTests/PeekTests.swift index 990055af47..de47c5fd85 100644 --- a/Tests/ParsingTests/PeekTests.swift +++ b/Tests/ParsingTests/PeekTests.swift @@ -5,7 +5,7 @@ class PeekTests: XCTestCase { func testPeekMatches() throws { var input = "_foo1 = nil"[...] - let identifier = Parse { + let identifier = Parse(input: Substring.self) { Peek { Prefix(1) { $0.isLetter || $0 == "_" } } Prefix { $0.isNumber || $0.isLetter || $0 == "_" } } @@ -17,7 +17,7 @@ class PeekTests: XCTestCase { func testPeekFails() throws { var input = "1foo = nil"[...] - let identifier = Parse { + let identifier = Parse(input: Substring.self) { Peek { Prefix(1) { $0.isLetter || $0 == "_" } } Prefix { $0.isNumber || $0.isLetter || $0 == "_" } } @@ -61,7 +61,7 @@ class PeekTests: XCTestCase { func testPrintSkippedPeekSucceeds() { var input = "!"[...] - let identifier = Parse { + let identifier = Parse(input: Substring.self) { Peek { Prefix(1) { $0.isLetter || $0 == "_" } } @@ -76,7 +76,7 @@ class PeekTests: XCTestCase { func testPrintSkippedPeekSucceedsUnexpectedly() { var input = "!"[...] - let identifier = Parse { + let identifier = Parse(input: Substring.self) { Peek { Prefix(1) { $0.isLetter || $0 == "_" } } diff --git a/Tests/ParsingTests/PipeTests.swift b/Tests/ParsingTests/PipeTests.swift index a8e86e8549..0723a3f107 100644 --- a/Tests/ParsingTests/PipeTests.swift +++ b/Tests/ParsingTests/PipeTests.swift @@ -49,4 +49,18 @@ final class PipeTests: XCTestCase { } XCTAssertEqual("true", Substring(input)) } + + func testUsingDownstreamInput() { + let utf8InputParser = Parse(input: Substring.UTF8View.self) { + Always("Hello world"[...]) + } + let pipedParser = utf8InputParser.pipe { + Parse(input: Substring.self) { + Always("123") + } + } + var input = ""[...].utf8 + let output = pipedParser.parse(&input) + XCTAssertEqual("123", output) + } } diff --git a/Tests/ParsingTests/PrefixTests.swift b/Tests/ParsingTests/PrefixTests.swift index 70fbace0a1..e61ca79f15 100644 --- a/Tests/ParsingTests/PrefixTests.swift +++ b/Tests/ParsingTests/PrefixTests.swift @@ -89,11 +89,13 @@ final class PrefixTests: XCTestCase { } func testPrintUpstreamInputFailure() { - let p = ParsePrint { - Prefix { $0 != "\n" } - First() + struct MyParserPrinter: ParserPrinter { + var body: some ParserPrinter { + Prefix { $0 != "\n" } + First() + } } - XCTAssertThrowsError(try p.print(("Hello", " "))) { error in + XCTAssertThrowsError(try MyParserPrinter().print(("Hello", " "))) { error in XCTAssertEqual( """ error: round-trip expectation failed @@ -109,10 +111,12 @@ final class PrefixTests: XCTestCase { } func testPrintWithMaxCountAllowMatchingNextElement() { - let p = ParsePrint { - Prefix(3) { $0.isNumber } - First() + struct MyParserPrinter: ParserPrinter { + var body: some ParserPrinter { + Prefix(3) { $0.isNumber } + First() + } } - XCTAssertEqual("1230", try p.print(("123", "0"))) + XCTAssertEqual("1230", try MyParserPrinter().print(("123", "0"))) } } diff --git a/Tests/ParsingTests/RegressionTests.swift b/Tests/ParsingTests/RegressionTests.swift new file mode 100644 index 0000000000..bad890f9ea --- /dev/null +++ b/Tests/ParsingTests/RegressionTests.swift @@ -0,0 +1,14 @@ +import Parsing + +// https://github.com/pointfreeco/swift-parsing/discussions/290#discussioncomment-5439338 +enum ValueOrEmpty { + case value(Double) + case empty + + static func parser() -> some Parser { + OneOf { + Double.parser().map(Self.value) + "".map { .empty } + } + } +} diff --git a/Tests/ParsingTests/ReplaceErrorTests.swift b/Tests/ParsingTests/ReplaceErrorTests.swift index 0f4fb93589..628a3b061e 100644 --- a/Tests/ParsingTests/ReplaceErrorTests.swift +++ b/Tests/ParsingTests/ReplaceErrorTests.swift @@ -6,7 +6,7 @@ final class ReplaceErrorTests: XCTestCase { var input = "123"[...] XCTAssertEqual( 0, - Parse { + Parse(input: Substring.self) { Int.parser() "!" }.replaceError(with: 0).parse(&input)) diff --git a/Tests/ParsingTests/RestTests.swift b/Tests/ParsingTests/RestTests.swift index 23f15b7f53..2b7f9d5335 100644 --- a/Tests/ParsingTests/RestTests.swift +++ b/Tests/ParsingTests/RestTests.swift @@ -25,7 +25,7 @@ final class RestTests: XCTestCase { } func testPrintRest() { - XCTAssertEqual(try Rest().print("Hello"), "Hello") + XCTAssertEqual(try Rest().print("Hello"[...]), "Hello") } func testPrintRestFailsOnUpcoming() throws { @@ -47,7 +47,7 @@ final class RestTests: XCTestCase { } func testPrintRestFailsOnEmpty() throws { - XCTAssertThrowsError(try Rest().print("")) { error in + XCTAssertThrowsError(try Rest().print(""[...])) { error in XCTAssertEqual( """ error: round-trip expectation failed diff --git a/Tests/ParsingTests/SkipTests.swift b/Tests/ParsingTests/SkipTests.swift index 5cf2621592..93ce8494f6 100644 --- a/Tests/ParsingTests/SkipTests.swift +++ b/Tests/ParsingTests/SkipTests.swift @@ -4,13 +4,15 @@ import XCTest final class SkipTests: XCTestCase { func testSkipSuccess() { var input = "42 Hello, world!"[...].utf8 - XCTAssert(try () == XCTUnwrap(Skip { Int.parser() }.parse(&input))) + XCTAssert(try () == XCTUnwrap(Skip { Int.parser(of: Substring.UTF8View.self) }.parse(&input))) XCTAssertEqual(" Hello, world!", Substring(input)) } func testSkipFailure() { var input = "Hello, world!"[...].utf8 - XCTAssertThrowsError(try Skip { Int.parser() }.parse(&input)) { error in + XCTAssertThrowsError( + try Skip { Int.parser(of: Substring.UTF8View.self) }.parse(&input) + ) { error in XCTAssertEqual( """ error: unexpected input diff --git a/Tests/ParsingTests/UTF8Tests.swift b/Tests/ParsingTests/UTF8Tests.swift index f7ae76fc31..bb23560319 100644 --- a/Tests/ParsingTests/UTF8Tests.swift +++ b/Tests/ParsingTests/UTF8Tests.swift @@ -4,7 +4,7 @@ import XCTest final class UTF8Tests: XCTestCase { func testSubstringNormalization() { var input = "\u{00E9}e\u{0301}e\u{0341} Hello, world"[...].utf8 - let parser = From(.substring) { "é" } + let parser = From(.substring) { "é" } XCTAssertNoThrow(try parser.parse(&input)) XCTAssertEqual("e\u{0301}e\u{0341} Hello, world", Substring(input)) XCTAssertNoThrow(try parser.parse(&input))