@@ -147,7 +147,7 @@ extension Parser {
147147 return RawTokenSyntax (
148148 kind: token. tokenKind,
149149 text: SyntaxText ( rebasing: token. tokenText. dropFirst ( reclassifyLeading. count) . dropLast ( reclassifyTrailing. count) ) ,
150- leadingTriviaPieces: token. leadingTriviaPieces + TriviaParser. parseTrivia ( reclassifyLeading, position: . trailing ) ,
150+ leadingTriviaPieces: token. leadingTriviaPieces + TriviaParser. parseTrivia ( reclassifyLeading, position: . leading ) ,
151151 trailingTriviaPieces: TriviaParser . parseTrivia ( reclassifyTrailing, position: . trailing) + token. trailingTriviaPieces,
152152 presence: token. presence,
153153 tokenDiagnostic: token. tokenView. tokenDiagnostic ?? tokenDiagnostic,
@@ -595,10 +595,105 @@ extension Parser {
595595 )
596596 }
597597 }
598+
599+ mutating func parseSimpleString( ) -> RawSimpleStringLiteralExprSyntax {
600+ let openDelimiter = self . consume ( if: . rawStringPoundDelimiter)
601+ let ( unexpectedBeforeOpenQuote, openQuote) = self . expect ( anyIn: SimpleStringLiteralExprSyntax . OpenQuoteOptions. self, default: . stringQuote)
602+
603+ /// Parse segments.
604+ var segments : [ RawStringSegmentSyntax ] = [ ]
605+ var loopProgress = LoopProgressCondition ( )
606+ while hasProgressed ( & loopProgress) {
607+ // If we encounter a token with leading trivia, we're no longer in the
608+ // string literal.
609+ guard currentToken. leadingTriviaText. isEmpty else { break }
610+
611+ if let stringSegment = self . consume ( if: . stringSegment, TokenSpec ( . identifier, remapping: . stringSegment) ) {
612+ var unexpectedAfterContent : RawUnexpectedNodesSyntax ?
613+
614+ if let ( backslash, leftParen) = self . consume ( if: . backslash, followedBy: . leftParen) {
615+ var unexpectedTokens : [ RawSyntax ] = [ RawSyntax ( backslash) , RawSyntax ( leftParen) ]
616+
617+ let ( unexpectedBeforeRightParen, rightParen) = self . expect ( TokenSpec ( . rightParen, allowAtStartOfLine: false ) )
618+ unexpectedTokens += unexpectedBeforeRightParen? . elements ?? [ ]
619+ unexpectedTokens. append ( RawSyntax ( rightParen) )
620+
621+ unexpectedAfterContent = RawUnexpectedNodesSyntax (
622+ unexpectedTokens,
623+ arena: self . arena
624+ )
625+ }
626+
627+ segments. append ( RawStringSegmentSyntax ( content: stringSegment, unexpectedAfterContent, arena: self . arena) )
628+ } else {
629+ break
630+ }
631+ }
632+
633+ let ( unexpectedBetweenSegmentAndCloseQuote, closeQuote) = self . expect (
634+ anyIn: SimpleStringLiteralExprSyntax . CloseQuoteOptions. self,
635+ default: openQuote. closeTokenKind
636+ )
637+ let closeDelimiter = self . consume ( if: . rawStringPoundDelimiter)
638+
639+ if openQuote. tokenKind == . multilineStringQuote, !openQuote. isMissing, !closeQuote. isMissing {
640+ let postProcessed = postProcessMultilineStringLiteral (
641+ rawStringDelimitersToken: openDelimiter,
642+ openQuote: openQuote,
643+ segments: segments. compactMap { RawStringLiteralSegmentListSyntax . Element. stringSegment ( $0) } ,
644+ closeQuote: closeQuote
645+ )
646+
647+ return RawSimpleStringLiteralExprSyntax (
648+ RawUnexpectedNodesSyntax (
649+ combining: unexpectedBeforeOpenQuote,
650+ postProcessed. unexpectedBeforeOpeningQuote,
651+ openDelimiter,
652+ arena: self . arena
653+ ) ,
654+ openQuote: postProcessed. openingQuote,
655+ segments: RawSimpleStringLiteralSegmentsSyntax (
656+ elements: postProcessed. segments. compactMap { $0. as ( RawStringSegmentSyntax . self) } ,
657+ arena: self . arena
658+ ) ,
659+ unexpectedBetweenSegmentAndCloseQuote,
660+ closeQuote: postProcessed. closingQuote,
661+ RawUnexpectedNodesSyntax (
662+ combining: closeDelimiter,
663+ postProcessed. unexpectedBeforeClosingQuote,
664+ arena: self . arena
665+ ) ,
666+ arena: self . arena
667+ )
668+ } else {
669+ return RawSimpleStringLiteralExprSyntax (
670+ RawUnexpectedNodesSyntax ( combining: unexpectedBeforeOpenQuote, openDelimiter, arena: self . arena) ,
671+ openQuote: openQuote,
672+ segments: RawSimpleStringLiteralSegmentsSyntax ( elements: segments, arena: self . arena) ,
673+ unexpectedBetweenSegmentAndCloseQuote,
674+ closeQuote: closeQuote,
675+ RawUnexpectedNodesSyntax ( [ closeDelimiter] , arena: self . arena) ,
676+ arena: self . arena
677+ )
678+ }
679+ }
598680}
599681
600682// MARK: - Utilities
601683
684+ fileprivate extension RawTokenSyntax {
685+ var closeTokenKind : SimpleStringLiteralExprSyntax . CloseQuoteOptions {
686+ switch self {
687+ case . multilineStringQuote:
688+ return . multilineStringQuote
689+ case . stringQuote:
690+ return . stringQuote
691+ default :
692+ return . stringQuote
693+ }
694+ }
695+ }
696+
602697fileprivate extension SyntaxText {
603698 private func hasSuffix( _ other: String ) -> Bool {
604699 var other = other
0 commit comments