@@ -123,7 +123,7 @@ extension Parser {
123123 ( . obsoleted, let handle) ? :
124124 let argumentLabel = self . eat ( handle)
125125 let ( unexpectedBeforeColon, colon) = self . expect ( . colon)
126- let version = self . parseVersionTuple ( )
126+ let version = self . parseVersionTuple ( maxComponentCount : 3 )
127127 entry = . availabilityLabeledArgument(
128128 RawAvailabilityLabeledArgumentSyntax (
129129 label: argumentLabel,
@@ -136,7 +136,7 @@ extension Parser {
136136 case ( . deprecated, let handle) ? :
137137 let argumentLabel = self . eat ( handle)
138138 if let colon = self . consume ( if: . colon) {
139- let version = self . parseVersionTuple ( )
139+ let version = self . parseVersionTuple ( maxComponentCount : 3 )
140140 entry = . availabilityLabeledArgument(
141141 RawAvailabilityLabeledArgumentSyntax (
142142 label: argumentLabel,
@@ -227,7 +227,7 @@ extension Parser {
227227
228228 let version : RawVersionTupleSyntax ?
229229 if self . at ( . integerLiteral, . floatingLiteral) {
230- version = self . parseVersionTuple ( )
230+ version = self . parseVersionTuple ( maxComponentCount : 3 )
231231 } else {
232232 version = nil
233233 }
@@ -258,47 +258,47 @@ extension Parser {
258258 /// Grammar
259259 /// =======
260260 ///
261- /// platform- version → decimal-digits
262- /// platform- version → decimal-digits '.' decimal-digits
263- /// platform- version → decimal-digits '.' decimal-digits '.' decimal-digits
264- mutating func parseVersionTuple( ) -> RawVersionTupleSyntax {
261+ /// version-tuple -> integer-literal version-list?
262+ /// version-list -> version-tuple-element version-list?
263+ /// version-tuple-element -> '.' interger-literal
264+ mutating func parseVersionTuple( maxComponentCount : Int ) -> RawVersionTupleSyntax {
265265 if self . at ( . floatingLiteral) ,
266266 let periodIndex = self . currentToken. tokenText. firstIndex ( of: UInt8 ( ascii: " . " ) ) ,
267267 self . currentToken. tokenText [ 0 ..< periodIndex] . allSatisfy ( { Unicode . Scalar ( $0) . isDigit } )
268268 {
269269 // The lexer generates a float literal '1.2' for the major and minor version.
270270 // Split it into two integers if possible
271271 let major = self . consumePrefix ( SyntaxText ( rebasing: self . currentToken. tokenText [ 0 ..< periodIndex] ) , as: . integerLiteral)
272- let ( unexpectedBeforeMinorPeriod, minorPeriod) = self . expect ( . period)
273- let minor = self . expectDecimalIntegerWithoutRecovery ( )
274- let patchPeriod : RawTokenSyntax ?
275- let patch : RawTokenSyntax ?
276- if let period = self . consume ( if: . period) {
277- patchPeriod = period
278- patch = self . expectDecimalIntegerWithoutRecovery ( )
279- } else {
280- patchPeriod = nil
281- patch = nil
272+
273+ var components : [ RawVersionComponentSyntax ] = [ ]
274+ var trailingComponents : [ RawVersionComponentSyntax ] = [ ]
275+
276+ for i in 1 ... {
277+ guard let period = self . consume ( if: . period) else {
278+ break
279+ }
280+ let version = self . expectDecimalIntegerWithoutRecovery ( )
281+
282+ let versionComponent = RawVersionComponentSyntax ( period: period, number: version, arena: self . arena)
283+
284+ if i < maxComponentCount {
285+ components. append ( versionComponent)
286+ } else {
287+ trailingComponents. append ( versionComponent)
288+ }
282289 }
283- return RawVersionTupleSyntax (
284- major : major ,
285- unexpectedBeforeMinorPeriod ,
286- minorPeriod : minorPeriod ,
287- minor : minor ,
288- patchPeriod : patchPeriod ,
289- patch : patch ,
290- arena: self . arena
291- )
290+
291+ var unexpectedTrailingComponents : RawUnexpectedNodesSyntax ?
292+
293+ if ! trailingComponents . isEmpty {
294+ unexpectedTrailingComponents = RawUnexpectedNodesSyntax ( elements : trailingComponents . compactMap { $0 . as ( RawSyntax . self ) } , arena : self . arena )
295+ }
296+
297+ return RawVersionTupleSyntax ( major : major , components : RawVersionComponentListSyntax ( elements : components , arena: self . arena) , unexpectedTrailingComponents , arena : self . arena )
298+
292299 } else {
293300 let major = self . expectDecimalIntegerWithoutRecovery ( )
294- return RawVersionTupleSyntax (
295- major: major,
296- minorPeriod: nil ,
297- minor: nil ,
298- patchPeriod: nil ,
299- patch: nil ,
300- arena: self . arena
301- )
301+ return RawVersionTupleSyntax ( major: major, components: nil , arena: self . arena)
302302 }
303303 }
304304}
0 commit comments