docs: @SuppressWarnings("PMD.NcssCount")
    static String expandEscapedChars(String str) {
      StringBuilder builder = new StringBuilder();
      for (int i = 0; i < str.length(); ++i) {
        char c = str.charAt(i);
        if (c == '\\') {
          ++i;
          if (i >= str.length()) {
            throw error("dangling escape", str, i);
          }
          c = str.charAt(i);
          switch (c) {
            case 't': builder.append('\t'); break;
            case 'n': builder.append('\n'); break;
            case 'r': builder.append('\r'); break;
            case 'f': builder.append('\f'); break;
            case 'a': builder.append('\u0007'); break;
            case 'e': builder.append('\u001B'); break;
            case '0':
              int numDigits = 0;
              for (int j = i + 1; j < Math.min(i + 4, str.length()); ++j) {
                c = str.charAt(j);
                if (c >= '0' && c <= '7') {
                  ++numDigits;
                } else {
                  break;
                }
              }
              if (numDigits < 1 || numDigits > 3) {
                throw error("invalid octal escape sequence", str, i);
              }
              c = parse(str.substring(i + 1, i + numDigits + 1), 8, "octal", str, i);
              builder.append(c);
              i += numDigits;
              break;
            case 'x':
              if (i + 3 > str.length()) {
                throw error("invalid hexadecimal escape sequence", str, i);
              }
              c = parse(str.substring(i + 1, i + 3), 16, "hexadecimal", str, i);
              builder.append(c);
              i += 2;
              break;
            case 'u':
              if (i + 5 > str.length()) {
                throw error("invalid unicode escape sequence", str, i);
              }
              c = parse(str.substring(i + 1, i + 5), 16, "unicode", str, i);
              builder.append(c);
              i += 4;
              break;
            default:
              builder.append('\\').append(c);
              break;
          }
        } else {
          builder.append(c);
        }
      }
      return builder.toString();
    }