Skip to content

Commit 7b293c9

Browse files
committed
Eliminate eat from the parser
Use one of the following alternatives instead: - `expect` (mostly at start of productions) - `consume(if:)` where this paradigm is applicable - `consume(if:followedBy:)` to consume two tokens at once - A new `at(anyIn:)` paradigm that allows the parser to check if it is currently positioned at a known token kind, which can be exhausitively switched. If this is the case, the token can be safely consumed using a handle. - This function might seem overly complicated at the moment but it should allow us to later switch to a similar function that also does recovery.
1 parent 37e791c commit 7b293c9

18 files changed

+623
-493
lines changed

Sources/SwiftParser/Attributes.swift

Lines changed: 40 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -178,24 +178,20 @@ extension Parser {
178178
return RawSyntax(self.parseCustomAttribute())
179179
}
180180

181-
let (unexpectedBeforeAtSign, atSign) = self.eat(.atSign)
181+
let (unexpectedBeforeAtSign, atSign) = self.expect(.atSign)
182182
let ident = self.consumeIdentifier()
183-
let unexpectedBeforeLeftParen: RawUnexpectedNodesSyntax?
184-
let leftParen: RawTokenSyntax?
183+
let leftParen = self.consume(if: .leftParen)
185184
let arg: RawSyntax?
186185
let unexpectedBeforeRightParen: RawUnexpectedNodesSyntax?
187186
let rightParen: RawTokenSyntax?
188-
if self.at(.leftParen) {
187+
if leftParen != nil {
189188
var args = [RawTokenSyntax]()
190-
(unexpectedBeforeLeftParen, leftParen) = self.eat(.leftParen)
191189
while !self.at(.eof), !self.at(.rightParen) {
192190
args.append(self.consumeAnyToken())
193191
}
194192
arg = RawSyntax(RawTokenListSyntax(elements: args, arena: self.arena))
195193
(unexpectedBeforeRightParen, rightParen) = self.expect(.rightParen)
196194
} else {
197-
unexpectedBeforeLeftParen = nil
198-
leftParen = nil
199195
arg = nil
200196
unexpectedBeforeRightParen = nil
201197
rightParen = nil
@@ -204,7 +200,6 @@ extension Parser {
204200
unexpectedBeforeAtSign,
205201
atSignToken: atSign,
206202
attributeName: ident,
207-
unexpectedBeforeLeftParen,
208203
leftParen: leftParen,
209204
argument: arg,
210205
unexpectedBeforeRightParen,
@@ -214,25 +209,25 @@ extension Parser {
214209
}
215210

216211
mutating func parseCustomAttribute() -> RawCustomAttributeSyntax {
217-
let (unexpectedBeforeAtSign, atSign) = self.eat(.atSign)
212+
let (unexpectedBeforeAtSign, atSign) = self.expect(.atSign)
218213
let attrName = self.parseType()
219214

220215
// Custom attributes are stricter than normal attributes about their
221216
// argument lists "immediately" following the attribute name.
222-
guard self.at(.leftParen) && !self.currentToken.isAtStartOfLine && self.lookahead().isCustomAttributeArgument() else {
217+
guard let leftParen = self.consume(if: .leftParen, where: { (lexeme, parser) in
218+
lexeme.isAtStartOfLine && parser.lookahead().isCustomAttributeArgument()
219+
}) else {
223220
return RawCustomAttributeSyntax(
224221
atSignToken: atSign, attributeName: attrName,
225222
leftParen: nil, argumentList: nil, rightParen: nil,
226223
arena: self.arena)
227224
}
228-
let (unexpectedBeforeLeftParen, leftParen) = self.eat(.leftParen)
229225
let arguments = self.parseArgumentListElements()
230226
let (unexpectedBeforeRightParen, rightParen) = self.expect(.rightParen)
231227
return RawCustomAttributeSyntax(
232228
unexpectedBeforeAtSign,
233229
atSignToken: atSign,
234230
attributeName: attrName,
235-
unexpectedBeforeLeftParen,
236231
leftParen: leftParen,
237232
argumentList: RawTupleExprElementListSyntax(elements: arguments, arena: self.arena),
238233
unexpectedBeforeRightParen,
@@ -243,7 +238,7 @@ extension Parser {
243238

244239
extension Parser {
245240
mutating func parseAvailabilityAttribute() -> RawAttributeSyntax {
246-
let (unexpectedBeforeAtSign, atSign) = self.eat(.atSign)
241+
let (unexpectedBeforeAtSign, atSign) = self.expect(.atSign)
247242
assert(self.currentToken.tokenText == "available")
248243
let available = self.consumeAnyToken()
249244
let (unexpectedBeforeLeftParen, leftParen) = self.expect(.leftParen)
@@ -276,7 +271,7 @@ extension Parser {
276271

277272
extension Parser {
278273
mutating func parseDifferentiableAttribute() -> RawAttributeSyntax {
279-
let (unexpectedBeforeAtSign, atSign) = self.eat(.atSign)
274+
let (unexpectedBeforeAtSign, atSign) = self.expect(.atSign)
280275
assert(self.currentToken.tokenText == "differentiable")
281276
let differentiable = self.consumeAnyToken()
282277
let (unexpectedBeforeLeftParen, leftParen) = self.expect(.leftParen)
@@ -346,7 +341,7 @@ extension Parser {
346341
let wrt = self.consumeIdentifier()
347342
let (unexpectedBeforeColon, colon) = self.expect(.colon)
348343

349-
guard self.at(.leftParen) else {
344+
guard let leftParen = self.consume(if: .leftParen) else {
350345
// If no opening '(' for parameter list, parse a single parameter.
351346
let param = self.parseDifferentiabilityParameter().map(RawSyntax.init(_:))
352347
?? RawSyntax(RawMissingSyntax(arena: self.arena))
@@ -359,7 +354,6 @@ extension Parser {
359354
)
360355
}
361356

362-
let (unexpectedBeforeLeftParen, leftParen) = self.eat(.leftParen)
363357
var elements = [RawDifferentiabilityParamSyntax]()
364358
while !self.at(.eof) && !self.at(.rightParen) {
365359
guard let param = self.parseDifferentiabilityParameter() else {
@@ -371,7 +365,6 @@ extension Parser {
371365

372366
let parameters = RawDifferentiabilityParamListSyntax(elements: elements, arena: self.arena)
373367
let list = RawDifferentiabilityParamsSyntax(
374-
unexpectedBeforeLeftParen,
375368
leftParen: leftParen,
376369
diffParams: parameters,
377370
unexpectedBeforeRightParen,
@@ -388,50 +381,59 @@ extension Parser {
388381
}
389382

390383
mutating func parseDifferentiabilityParameter() -> RawDifferentiabilityParamSyntax? {
391-
switch self.currentToken.tokenKind {
392-
case .identifier:
393-
let token = self.consumeIdentifier()
384+
enum ExpectedTokenKind: RawTokenKindSubset {
385+
case identifier
386+
case integerLiteral
387+
case selfKeyword
388+
389+
var rawTokenKind: RawTokenKind {
390+
switch self {
391+
case .identifier: return .identifier
392+
case .integerLiteral: return .integerLiteral
393+
case .selfKeyword: return .selfKeyword
394+
}
395+
}
396+
}
397+
398+
switch self.at(anyIn: ExpectedTokenKind.self) {
399+
case (.identifier, let handle)?:
400+
let token = self.eat(handle)
394401
let comma = self.consume(if: .comma)
395402
return RawDifferentiabilityParamSyntax(
396403
parameter: RawSyntax(token), trailingComma: comma, arena: self.arena)
397-
case .integerLiteral:
398-
let token = self.consumeAnyToken()
404+
case (.integerLiteral, let handle)?:
405+
let token = self.eat(handle)
399406
let comma = self.consume(if: .comma)
400407
return RawDifferentiabilityParamSyntax(
401408
parameter: RawSyntax(token), trailingComma: comma, arena: self.arena)
402-
case .selfKeyword:
403-
let (unexpectedBeforeToken, token) = self.eat(.selfKeyword)
409+
case (.selfKeyword, let handle)?:
410+
let token = self.eat(handle)
404411
let comma = self.consume(if: .comma)
405412
return RawDifferentiabilityParamSyntax(
406-
unexpectedBeforeToken,
407413
parameter: RawSyntax(token),
408414
trailingComma: comma,
409415
arena: self.arena
410416
)
411-
default:
417+
case nil:
412418
return nil
413419
}
414420
}
415421
}
416422

417423
extension Parser {
418424
mutating func parseObjectiveCAttribute() -> RawAttributeSyntax {
419-
let (unexpectedBeforeAtSign, atSign) = self.eat(.atSign)
425+
let (unexpectedBeforeAtSign, atSign) = self.expect(.atSign)
420426
assert(self.currentToken.tokenText == "objc")
421427
let objc = self.consumeAnyToken()
422428

423-
let unexpectedBeforeLeftParen: RawUnexpectedNodesSyntax?
424-
let leftParen: RawTokenSyntax?
429+
let leftParen = self.consume(if: .leftParen)
425430
let argument: RawObjCSelectorSyntax?
426431
let unexpectedBeforeRightParen: RawUnexpectedNodesSyntax?
427432
let rightParen: RawTokenSyntax?
428-
if self.at(.leftParen) {
429-
(unexpectedBeforeLeftParen, leftParen) = self.eat(.leftParen)
433+
if leftParen != nil {
430434
argument = self.parseObjectiveCSelector()
431435
(unexpectedBeforeRightParen, rightParen) = self.expect(.rightParen)
432436
} else {
433-
unexpectedBeforeLeftParen = nil
434-
leftParen = nil
435437
argument = nil
436438
unexpectedBeforeRightParen = nil
437439
rightParen = nil
@@ -441,7 +443,6 @@ extension Parser {
441443
unexpectedBeforeAtSign,
442444
atSignToken: atSign,
443445
attributeName: objc,
444-
unexpectedBeforeLeftParen,
445446
leftParen: leftParen,
446447
argument: argument.map(RawSyntax.init),
447448
unexpectedBeforeRightParen,
@@ -454,11 +455,9 @@ extension Parser {
454455
var elements = [RawObjCSelectorPieceSyntax]()
455456
while !self.at(.eof) && !self.at(.rightParen) {
456457
// Empty selector piece.
457-
if self.at(.colon) {
458-
let (unexpectedBeforeColon, colon) = self.eat(.colon)
458+
if let colon = self.consume(if: .colon) {
459459
elements.append(RawObjCSelectorPieceSyntax(
460460
name: nil,
461-
unexpectedBeforeColon,
462461
colon: colon,
463462
arena: self.arena
464463
))
@@ -481,7 +480,7 @@ extension Parser {
481480

482481
extension Parser {
483482
mutating func parseSpecializeAttribute() -> RawAttributeSyntax {
484-
let (unexpectedBeforeAtSign, atSign) = self.eat(.atSign)
483+
let (unexpectedBeforeAtSign, atSign) = self.expect(.atSign)
485484
assert(self.currentToken.tokenText == "_specialize")
486485
let specializeToken = self.consumeAnyToken()
487486
let (unexpectedBeforeLeftParen, leftParen) = self.expect(.leftParen)
@@ -654,7 +653,7 @@ extension Parser {
654653

655654
extension Parser {
656655
mutating func parsePrivateImportAttribute() -> RawAttributeSyntax {
657-
let (unexpectedBeforeAtSign, atSign) = self.eat(.atSign)
656+
let (unexpectedBeforeAtSign, atSign) = self.expect(.atSign)
658657
assert(self.currentToken.tokenText == "_private")
659658
let privateToken = self.consumeAnyToken()
660659
let (unexpectedBeforeLeftParen, leftParen) = self.expect(.leftParen)
@@ -684,7 +683,7 @@ extension Parser {
684683

685684
extension Parser {
686685
mutating func parseDynamicReplacementAttribute() -> RawAttributeSyntax {
687-
let (unexpectedBeforeAtSign, atSign) = self.eat(.atSign)
686+
let (unexpectedBeforeAtSign, atSign) = self.expect(.atSign)
688687
assert(self.currentToken.tokenText == "_dynamicReplacement")
689688
let dynamicReplacementToken = self.consumeAnyToken()
690689
let (unexpectedBeforeLeftParen, leftParen) = self.expect(.leftParen)
@@ -722,7 +721,7 @@ extension Parser {
722721

723722
extension Parser {
724723
mutating func parseSPIAttribute() -> RawAttributeSyntax {
725-
let (unexpectedBeforeAtSign, atSign) = self.eat(.atSign)
724+
let (unexpectedBeforeAtSign, atSign) = self.expect(.atSign)
726725
assert(self.currentToken.tokenText == "_spi")
727726
let spiToken = self.consumeAnyToken()
728727
let (unexpectedBeforeLeftParen, leftParen) = self.expect(.leftParen)

Sources/SwiftParser/Availability.swift

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -128,12 +128,10 @@ extension Parser {
128128
))
129129
case .deprecated:
130130
let argumentLabel = self.consumeAnyToken()
131-
if self.at(.colon) {
132-
let (unexpectedBeforeColon, colon) = self.eat(.colon)
131+
if let colon = self.consume(if: .colon) {
133132
let version = self.parseVersionTuple()
134133
entry = RawSyntax(RawAvailabilityLabeledArgumentSyntax(
135134
label: argumentLabel,
136-
unexpectedBeforeColon,
137135
colon: colon,
138136
value: RawSyntax(version),
139137
arena: self.arena

0 commit comments

Comments
 (0)