@@ -15,14 +15,14 @@ import AST
1515import Basic
1616
1717#if canImport(_CompilerRegexParser)
18- import _CompilerRegexParser
18+ @ _spi ( CompilerInterface ) import _CompilerRegexParser
1919
2020public func registerRegexParser( ) {
2121 Parser_registerRegexLiteralParsingFn ( _RegexLiteralParsingFn)
2222 Parser_registerRegexLiteralLexingFn ( _RegexLiteralLexingFn)
2323}
2424
25- /// Bridging between C++ lexer and _CompilerRegexParser.lexRegex()
25+ /// Bridging between C++ lexer and swiftCompilerLexRegexLiteral.
2626///
2727/// Attempt to lex a regex literal string.
2828///
@@ -50,47 +50,29 @@ private func _RegexLiteralLexingFn(
5050) -> /*CompletelyErroneous*/ CBool {
5151 let inputPtr = curPtrPtr. pointee
5252
53- do {
54- let ( _, _, endPtr) = try lexRegex ( start: inputPtr, end: bufferEndPtr)
55- curPtrPtr. pointee = endPtr. assumingMemoryBound ( to: CChar . self)
53+ guard let ( resumePtr, error) = swiftCompilerLexRegexLiteral (
54+ start: inputPtr, bufferEnd: bufferEndPtr, mustBeRegex: mustBeRegex
55+ ) else {
56+ // Not a regex literal, fallback without advancing the pointer.
5657 return false
57- } catch let error as DelimiterLexError {
58- if !mustBeRegex {
59- // This token can be something else. Let the client fallback.
60- return false ;
61- }
62- if error. kind == . unknownDelimiter {
63- // An unknown delimiter should be recovered from, as we may want to try
64- // lex something else.
65- return false
66- }
58+ }
6759
60+ // Advance the current pointer.
61+ curPtrPtr. pointee = resumePtr. assumingMemoryBound ( to: CChar . self)
62+
63+ if let error = error {
64+ // Emit diagnostic if diagnostics are enabled.
6865 if let diagEngine = DiagnosticEngine ( bridged: bridgedDiagnosticEngine) {
69- // Emit diagnostic.
7066 let startLoc = SourceLoc (
71- locationInFile: UnsafeRawPointer ( inputPtr) . assumingMemoryBound ( to: UInt8 . self) ) !
72- diagEngine. diagnose ( startLoc, . regex_literal_parsing_error, " \( error) " )
73- }
74-
75- // Advance the current pointer.
76- curPtrPtr. pointee = error. resumePtr. assumingMemoryBound ( to: CChar . self)
77-
78- switch error. kind {
79- case . unterminated, . multilineClosingNotOnNewline:
80- // These can be recovered from.
81- return false
82- case . unprintableASCII, . invalidUTF8:
83- // We don't currently have good recovery behavior for these.
84- return true
85- case . unknownDelimiter:
86- fatalError ( " Already handled " )
67+ locationInFile: error. location. assumingMemoryBound ( to: UInt8 . self) ) !
68+ diagEngine. diagnose ( startLoc, . regex_literal_parsing_error, error. message)
8769 }
88- } catch {
89- fatalError ( " Should be a DelimiterLexError " )
70+ return error. completelyErroneous
9071 }
72+ return false
9173}
9274
93- /// Bridging between C++ parser and _CompilerRegexParser.parseWithDelimiters()
75+ /// Bridging between C++ parser and swiftCompilerParseRegexLiteral.
9476///
9577/// - Parameters:
9678/// - inputPtr: A null-terminated C string.
@@ -103,6 +85,8 @@ private func _RegexLiteralLexingFn(
10385/// greater than or equal to `strlen(inputPtr)`.
10486/// - bridgedDiagnosticBaseLoc: Source location of the start of the literal
10587/// - bridgedDiagnosticEngine: Diagnostic engine to emit diagnostics.
88+ ///
89+ /// - Returns: `true` if there was a parse error, `false` otherwise.
10690public func _RegexLiteralParsingFn(
10791 _ inputPtr: UnsafePointer < CChar > ,
10892 _ versionOut: UnsafeMutablePointer < CUnsignedInt > ,
@@ -111,30 +95,27 @@ public func _RegexLiteralParsingFn(
11195 _ bridgedDiagnosticBaseLoc: BridgedSourceLoc ,
11296 _ bridgedDiagnosticEngine: BridgedDiagnosticEngine
11397) -> Bool {
114- versionOut. pointee = currentRegexLiteralFormatVersion
115-
11698 let str = String ( cString: inputPtr)
99+ let captureBuffer = UnsafeMutableRawBufferPointer (
100+ start: captureStructureOut, count: Int ( captureStructureSize) )
117101 do {
118- let ast = try parseWithDelimiters ( str)
119- // Serialize the capture structure for later type inference.
120- assert ( captureStructureSize >= str. utf8. count)
121- let buffer = UnsafeMutableRawBufferPointer (
122- start: captureStructureOut, count: Int ( captureStructureSize) )
123- ast. captureStructure. encode ( to: buffer)
124- return false ;
125- } catch {
102+ // FIXME: We need to plumb through the 'regexToEmit' result to the caller.
103+ // For now, it is the same as the input.
104+ let ( _, version) = try swiftCompilerParseRegexLiteral (
105+ str, captureBufferOut: captureBuffer)
106+ versionOut. pointee = CUnsignedInt ( version)
107+ return false
108+ } catch let error as CompilerParseError {
126109 var diagLoc = SourceLoc ( bridged: bridgedDiagnosticBaseLoc)
127110 let diagEngine = DiagnosticEngine ( bridged: bridgedDiagnosticEngine)
128- if let _diagLoc = diagLoc,
129- let locatedError = error as? LocatedErrorProtocol {
130- let offset = str. utf8. distance ( from: str. startIndex,
131- to: locatedError. location. start)
111+ if let _diagLoc = diagLoc, let errorLoc = error. location {
112+ let offset = str. utf8. distance ( from: str. startIndex, to: errorLoc)
132113 diagLoc = _diagLoc. advanced ( by: offset)
133114 }
134- diagEngine. diagnose (
135- diagLoc, . regex_literal_parsing_error,
136- " cannot parse regular expression: \( String ( describing: error) ) " )
115+ diagEngine. diagnose ( diagLoc, . regex_literal_parsing_error, error. message)
137116 return true
117+ } catch {
118+ fatalError ( " Expected CompilerParseError " )
138119 }
139120}
140121
0 commit comments