diff --git a/Sources/DSLConverter/Main.swift b/Sources/DSLConverter/Main.swift index 734e54b..fa2079c 100644 --- a/Sources/DSLConverter/Main.swift +++ b/Sources/DSLConverter/Main.swift @@ -22,7 +22,7 @@ struct Main { var standardError = FileHandle.standardError -extension FileHandle : TextOutputStream { +extension FileHandle: @retroactive TextOutputStream { public func write(_ string: String) { guard let data = string.data(using: .utf8) else { return } self.write(data) diff --git a/Sources/ExpressionParser/ExpressionParser.swift b/Sources/ExpressionParser/ExpressionParser.swift index 6ad9d48..197d3f9 100644 --- a/Sources/ExpressionParser/ExpressionParser.swift +++ b/Sources/ExpressionParser/ExpressionParser.swift @@ -4,6 +4,7 @@ import Foundation struct ExpressionParser { private(set) var tokens = [Token]() + private(set) var diagnostics: Diagnostics? private let pattern: String private let insensitive: Bool @@ -16,8 +17,9 @@ struct ExpressionParser { self.insensitive = insensitive } - mutating func parse() throws { - let ast = try _RegexParser.parse(pattern, .traditional) + mutating func parse() { + let ast = _RegexParser.parseWithRecovery(pattern, .traditional) + diagnostics = ast.diags emitNode(ast.root) } diff --git a/Sources/ExpressionParser/Main.swift b/Sources/ExpressionParser/Main.swift index 86322b9..15dfa7c 100644 --- a/Sources/ExpressionParser/Main.swift +++ b/Sources/ExpressionParser/Main.swift @@ -10,10 +10,15 @@ struct Main { .map { String($0) } var parser = ExpressionParser(pattern: pattern, insensitive: matchingOptions.contains("i")) - try parser.parse() + parser.parse() let data = try JSONEncoder().encode(parser.tokens) print(String(data: data, encoding: .utf8) ?? "") + if let diagnostics = parser.diagnostics { + for diag in diagnostics.diags { + print("\(diag.message)", to:&standardError) + } + } } catch { print("\(error)", to:&standardError) } @@ -22,7 +27,7 @@ struct Main { var standardError = FileHandle.standardError -extension FileHandle : TextOutputStream { +extension FileHandle: @retroactive TextOutputStream { public func write(_ string: String) { guard let data = string.data(using: .utf8) else { return } self.write(data) diff --git a/Sources/Matcher/Main.swift b/Sources/Matcher/Main.swift index d871c15..7c17232 100644 --- a/Sources/Matcher/Main.swift +++ b/Sources/Matcher/Main.swift @@ -29,7 +29,7 @@ struct Main { var standardError = FileHandle.standardError -extension FileHandle : TextOutputStream { +extension FileHandle: @retroactive TextOutputStream { public func write(_ string: String) { guard let data = string.data(using: .utf8) else { return } self.write(data) diff --git a/Tests/RegexTests/DebuggerTests.swift b/Tests/RegexTests/DebuggerTests.swift deleted file mode 100644 index 17f01f0..0000000 --- a/Tests/RegexTests/DebuggerTests.swift +++ /dev/null @@ -1,140 +0,0 @@ -import Foundation -import XCTest -@testable import Debugger - -class DebuggerTests: XCTestCase { - func testDebugPattern01() throws { - let pattern = #"a(b|c)"# - let text = "ac" - - try run(pattern: pattern, text: text, matchingOptions: []) - let stepCount = Context.shared.stepCount - - let context = Context.shared - for i in 1...stepCount { - try run(pattern: pattern, text: text, matchingOptions: [], until: i) - print("step: \(context.stepCount), start: \(context.start), current: \(context.current), \(text[text.index(text.startIndex, offsetBy: context.start)..>>>>>> branch-a - """ - - try run(pattern: pattern, text: text, matchingOptions: []) - let stepCount = Context.shared.stepCount - print("stepCount: \(stepCount)") - - let context = Context.shared - for i in 1...stepCount { - try run(pattern: pattern, text: text, matchingOptions: [], until: i) - print("step: \(context.stepCount), start: \(context.start), current: \(context.current), \(text[text.index(text.startIndex, offsetBy: context.start)..]*(((?'Open'<)[^<>]*)+((?'Close-Open'>)[^<>]*)+)*(?(Open)(?!))$"#) - try parser.parse() + parser.parse() print(parser.tokens) } do { var parser = ExpressionParser(pattern: #"hello"#) - try parser.parse() + parser.parse() print(parser.tokens) } do { var parser = ExpressionParser(pattern: #"gray|grey"#) - try parser.parse() + parser.parse() print(parser.tokens) } do { var parser = ExpressionParser(pattern: #"gr(a|e)y"#) - try parser.parse() + parser.parse() print(parser.tokens) } do { var parser = ExpressionParser(pattern: #"gr[ae]y"#) - try parser.parse() + parser.parse() print(parser.tokens) } do { var parser = ExpressionParser(pattern: #"colou?r"#) - try parser.parse() + parser.parse() print(parser.tokens) } do { var parser = ExpressionParser(pattern: #"rege(x(es)?|xps?)"#) - try parser.parse() + parser.parse() print(parser.tokens) } do { var parser = ExpressionParser(pattern: #"go*gle"#) - try parser.parse() + parser.parse() print(parser.tokens) } do { var parser = ExpressionParser(pattern: #"go+gle"#) - try parser.parse() + parser.parse() print(parser.tokens) } do { var parser = ExpressionParser(pattern: #"g(oog)+le"#) - try parser.parse() + parser.parse() print(parser.tokens) } do { var parser = ExpressionParser(pattern: #"z{3}"#) - try parser.parse() + parser.parse() print(parser.tokens) } do { var parser = ExpressionParser(pattern: #"z{3,6}"#) - try parser.parse() + parser.parse() print(parser.tokens) } do { var parser = ExpressionParser(pattern: #"z{3,}"#) - try parser.parse() + parser.parse() print(parser.tokens) } do { var parser = ExpressionParser(pattern: #"[Bb]rainf\*\*k"#) - try parser.parse() + parser.parse() print(parser.tokens) } do { var parser = ExpressionParser(pattern: #"\d"#) - try parser.parse() + parser.parse() print(parser.tokens) } do { var parser = ExpressionParser(pattern: #"\d+"#) - try parser.parse() + parser.parse() print(parser.tokens) } do { var parser = ExpressionParser(pattern: #"\d{5}(-\d{4})?"#) - try parser.parse() + parser.parse() print(parser.tokens) } do { var parser = ExpressionParser(pattern: #"1\d{10}"#) - try parser.parse() + parser.parse() print(parser.tokens) } do { var parser = ExpressionParser(pattern: #"[2-9]|[12]\d|3[0-6]"#) - try parser.parse() + parser.parse() print(parser.tokens) } do { var parser = ExpressionParser(pattern: #"Hello\nworld"#) - try parser.parse() + parser.parse() print(parser.tokens) } do { var parser = ExpressionParser(pattern: #"mi.....ft"#) - try parser.parse() + parser.parse() print(parser.tokens) } do { var parser = ExpressionParser(pattern: #"\d+(\.\d\d)?"#) - try parser.parse() + parser.parse() print(parser.tokens) } do { var parser = ExpressionParser(pattern: #"[^i*&2@]"#) - try parser.parse() + parser.parse() print(parser.tokens) } do { var parser = ExpressionParser(pattern: #"//[^\r\n]*[\r\n]"#) - try parser.parse() + parser.parse() print(parser.tokens) } do { var parser = ExpressionParser(pattern: #"^dog"#) - try parser.parse() + parser.parse() print(parser.tokens) } do { var parser = ExpressionParser(pattern: #"dog$"#) - try parser.parse() + parser.parse() print(parser.tokens) } do { var parser = ExpressionParser(pattern: #"^dog$"#) - try parser.parse() + parser.parse() print(parser.tokens) } do { var parser = ExpressionParser(pattern: #"\w++\d\d\w+"#) - try parser.parse() + parser.parse() print(parser.tokens) } do { var parser = ExpressionParser(pattern: #"<(\w+)>[^<]*"#) - try parser.parse() + parser.parse() print(parser.tokens) } do { var parser = ExpressionParser(pattern: #"Hillary(?=\s+Clinton)"#) - try parser.parse() + parser.parse() print(parser.tokens) } do { var parser = ExpressionParser(pattern: #"q(?!u)"#) - try parser.parse() + parser.parse() print(parser.tokens) } do { var parser = ExpressionParser(pattern: #"(?<=-)\p{L}+"#) - try parser.parse() + parser.parse() print(parser.tokens) } do { var parser = ExpressionParser(pattern: #"[\x41-\x45]{3}"#) - try parser.parse() + parser.parse() print(parser.tokens) } do { var parser = ExpressionParser(pattern: #"(?(?=regex)then|else)"#) - try parser.parse() + parser.parse() + print(parser.tokens) + } + do { + var parser = ExpressionParser(pattern: #"(?\w+)\W+(?<-word>\w+)"#) + parser.parse() print(parser.tokens) } }