 import Foundation
 
 public final class Resolver {
-    let tagNamePatternPairs: [(Tag.Name, NSRegularExpression)]
-    init(_ tagPatternPairs: [(Tag.Name, String)] = []) {
-        self.tagNamePatternPairs = tagPatternPairs.map { ($0.0, pattern($0.1)) }
+    public struct Rule {
+        public let tag: Tag.Name
+        let regexp: NSRegularExpression
+        public var pattern: String { return regexp.pattern }
+
+        public init(_ tag: Tag.Name, _ pattern: String) throws {
+            self.tag = tag
+            self.regexp = try .init(pattern: pattern, options: [])
+        }
     }
+
+    public let rules: [Rule]
+
+    init(_ rules: [Rule] = []) { self.rules = rules }
 
     public func resolveTag(of node: Node) -> Tag.Name {
         switch node {


extension Resolver {
    public static let basic = Resolver()
    public static let `default` = Resolver([
        (.bool, [
            "^(?:yes|Yes|YES|no|No|NO",
            "|true|True|TRUE|false|False|FALSE",
            "|on|On|ON|off|Off|OFF)$"
            ].joined()),
        (.int, [
            "^(?:[-+]?0b[0-1_]+",
            "|[-+]?0o?[0-7_]+",
            "|[-+]?(?:0|[1-9][0-9_]*)",
            "|[-+]?0x[0-9a-fA-F_]+",
            "|[-+]?[1-9][0-9_]*(?::[0-5]?[0-9])+)$"
            ].joined()),
        (.float, [
            "^(?:[-+]?(?:[0-9][0-9_]*)(?:\\.[0-9_]*)?(?:[eE][-+]?[0-9]+)?",
            "|\\.[0-9_]+(?:[eE][-+][0-9]+)?",
            "|[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\\.[0-9_]*",
            "|[-+]?\\.(?:inf|Inf|INF)",
            "|\\.(?:nan|NaN|NAN))$"
            ].joined()),
        (.merge, "^(?:<<)$"),
        (.null, [
            "^(?:~",
            "|null|Null|NULL",
            "|)$"
            ].joined()),
        (.timestamp, [
            "^(?:[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]",
            "|[0-9][0-9][0-9][0-9]-[0-9][0-9]?-[0-9][0-9]?",
            "(?:[Tt]|[ \\t]+)[0-9][0-9]?",
            ":[0-9][0-9]:[0-9][0-9](?:\\.[0-9]*)?",
            "(?:[ \\t]*(?:Z|[-+][0-9][0-9]?(?::[0-9][0-9])?))?)$"
            ].joined()),
        (.value, "^(?:=)$")
    ])
}

#if os(Linux)

    }

    func resolveTag(from string: String) -> Tag.Name {
        for rule in rules where rule.regexp.matches(in: string) {
            return rule.tag
        }
        return .str
    }
