@@ -15,14 +15,14 @@ import AST
15
15
import Basic
16
16
17
17
#if canImport(_CompilerRegexParser)
18
- import _CompilerRegexParser
18
+ @ _spi ( CompilerInterface ) import _CompilerRegexParser
19
19
20
20
public func registerRegexParser( ) {
21
21
Parser_registerRegexLiteralParsingFn ( _RegexLiteralParsingFn)
22
22
Parser_registerRegexLiteralLexingFn ( _RegexLiteralLexingFn)
23
23
}
24
24
25
- /// Bridging between C++ lexer and _CompilerRegexParser.lexRegex()
25
+ /// Bridging between C++ lexer and swiftCompilerLexRegexLiteral.
26
26
///
27
27
/// Attempt to lex a regex literal string.
28
28
///
@@ -50,47 +50,29 @@ private func _RegexLiteralLexingFn(
50
50
) -> /*CompletelyErroneous*/ CBool {
51
51
let inputPtr = curPtrPtr. pointee
52
52
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.
56
57
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
+ }
67
59
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.
68
65
if let diagEngine = DiagnosticEngine ( bridged: bridgedDiagnosticEngine) {
69
- // Emit diagnostic.
70
66
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)
87
69
}
88
- } catch {
89
- fatalError ( " Should be a DelimiterLexError " )
70
+ return error. completelyErroneous
90
71
}
72
+ return false
91
73
}
92
74
93
- /// Bridging between C++ parser and _CompilerRegexParser.parseWithDelimiters()
75
+ /// Bridging between C++ parser and swiftCompilerParseRegexLiteral.
94
76
///
95
77
/// - Parameters:
96
78
/// - inputPtr: A null-terminated C string.
@@ -103,6 +85,8 @@ private func _RegexLiteralLexingFn(
103
85
/// greater than or equal to `strlen(inputPtr)`.
104
86
/// - bridgedDiagnosticBaseLoc: Source location of the start of the literal
105
87
/// - bridgedDiagnosticEngine: Diagnostic engine to emit diagnostics.
88
+ ///
89
+ /// - Returns: `true` if there was a parse error, `false` otherwise.
106
90
public func _RegexLiteralParsingFn(
107
91
_ inputPtr: UnsafePointer < CChar > ,
108
92
_ versionOut: UnsafeMutablePointer < CUnsignedInt > ,
@@ -111,30 +95,27 @@ public func _RegexLiteralParsingFn(
111
95
_ bridgedDiagnosticBaseLoc: BridgedSourceLoc ,
112
96
_ bridgedDiagnosticEngine: BridgedDiagnosticEngine
113
97
) -> Bool {
114
- versionOut. pointee = currentRegexLiteralFormatVersion
115
-
116
98
let str = String ( cString: inputPtr)
99
+ let captureBuffer = UnsafeMutableRawBufferPointer (
100
+ start: captureStructureOut, count: Int ( captureStructureSize) )
117
101
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 {
126
109
var diagLoc = SourceLoc ( bridged: bridgedDiagnosticBaseLoc)
127
110
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)
132
113
diagLoc = _diagLoc. advanced ( by: offset)
133
114
}
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)
137
116
return true
117
+ } catch {
118
+ fatalError ( " Expected CompilerParseError " )
138
119
}
139
120
}
140
121
0 commit comments