 extension Int: ScalarConstructible {
     public static func construct(from node: Node) -> Int? {
         assert(node.isScalar) // swiftlint:disable:next force_unwrapping
-        var scalar = node.scalar!.string
-        scalar = scalar.replacingOccurrences(of: "_", with: "")
-        if scalar == "0" {
+        var scalarWithSign = node.scalar!.string
+        scalarWithSign = scalarWithSign.replacingOccurrences(of: "_", with: "")
+        if scalarWithSign == "0" {
             return 0
         }
+        let sign = scalarWithSign.hasPrefix("-") ? -1 : 1
+
+        let scalar = sign == -1 || scalarWithSign.hasPrefix("+") ?
+            scalarWithSign.substring(from: 1) : scalarWithSign.substring(from: 0)
         if scalar.hasPrefix("0x") {
-#if swift(>=4.0)
-            let hexadecimal = scalar[scalar.index(scalar.startIndex, offsetBy: 2)...]
-#else
-            let hexadecimal = scalar.substring(from: scalar.index(scalar.startIndex, offsetBy: 2))
-#endif
-            return Int(hexadecimal, radix: 16)
+            let hexadecimal = scalar.substring(from: 2)
+            return Int(hexadecimal, radix: 16).map { $0 * sign }
         }
         if scalar.hasPrefix("0b") {
-#if swift(>=4.0)
-            let octal = scalar[scalar.index(scalar.startIndex, offsetBy: 2)...]
-#else
-            let octal = scalar.substring(from: scalar.index(scalar.startIndex, offsetBy: 2))
-#endif
-            return Int(octal, radix: 2)
+            let octal = scalar.substring(from: 2)
+            return Int(octal, radix: 2).map { $0 * sign }
         }
         if scalar.hasPrefix("0o") {
-#if swift(>=4.0)
-            let octal = scalar[scalar.index(scalar.startIndex, offsetBy: 2)...]
-#else
-            let octal = scalar.substring(from: scalar.index(scalar.startIndex, offsetBy: 2))
-#endif
-            return Int(octal, radix: 8)
+            let octal = scalar.substring(from: 2)
+            return Int(octal, radix: 8).map { $0 * sign }
         }
         if scalar.hasPrefix("0") {
-#if swift(>=4.0)
-            let octal = scalar[scalar.index(after: scalar.startIndex)...]
-#else
-            let octal = scalar.substring(from: scalar.index(after: scalar.startIndex))
-#endif
-            return Int(octal, radix: 8)
+            let octal = scalar.substring(from: 1)
+            return Int(octal, radix: 8).map { $0 * sign }
         }
         if scalar.contains(":") {
-            return Int(sexagesimal: scalar)
-        }
-        return Int(scalar)
+            return Int(sexagesimal: scalar) * sign
+        }
+        return Int(scalar).map { $0 * sign }
     }
 }
 

}

fileprivate extension String {
    func substring(with range: NSRange) -> String? {
        guard range.location != NSNotFound else { return nil }
        let utf16lowerBound = utf16.index(utf16.startIndex, offsetBy: range.location)

        var sign: T = 1
        if scalar.hasPrefix("-") {
            sign = -1
            scalar = String(scalar.substring(from: 1))
        } else if scalar.hasPrefix("+") {
            scalar = String(scalar.substring(from: 1))
        }
        let digits = scalar.components(separatedBy: ":").flatMap({ T($0) }).reversed()
        var base: T = 1
