Пример #1
0
  /**
   * Parse a value.
   *
   * @param tb Source.
   * @param type The type of the array, may be any..
   * @param valueList Result added here.
   * @return Return true if a value has been added to the valueList and the cursor advanced or false
   *     and the cursor is as it was.
   */
  private static boolean value(Text t, DataType type, List<Object> valueList) {
    boolean result;

    if (t.isEof()) {
      result = false;
    } else if (t.consume("null")) {
      valueList.add(null);
      result = true;
    } else {
      switch (type) {
        case z:
        case Z:
        case f:
        case F:
          result = number(t, type, valueList);
          break;

        case text:
          result = text(t, valueList);
          break;

        case identifier:
          result = identifier(t, valueList);
          break;

        case path:
          result = path(t, valueList);
          break;

        case datetime:
          result = datetime(t, valueList);
          break;

        case date:
          result = date(t, valueList);
          break;

        case time:
          result = time(t, valueList);
          break;

        case bool:
          result = bool(t, valueList);
          break;

        case cardinality:
          result = cardinality(t, valueList);
          break;

        case any:
          result = any(t, valueList);
          break;

        default:
          throw new UnexpectedException("value: " + type);
      }
    }

    return result;
  }
Пример #2
0
  /**
   * Parse a string value and covert it to its proper data type.
   *
   * @param value
   * @return The parsed value.
   * @throws ParsingException Thrown if not Advisory is available and there was an error parsing.
   */
  @SuppressWarnings("unchecked")
  public static <T> T parseValue(String value) throws ParsingException {
    final T result;

    assert value != null;

    /*
     * todo Restructure the whole class so I've got parse and parseArray as
     * static methods and the share code properly.
     */
    if ("null".equals(value)) {
      result = null;
    } else {
      final List<Object> list = new ArrayList<>();
      final Text t = new Text();
      t.append(value);

      if (any(t, list) && t.isEof()) {
        result = (T) list.get(0);
      } else {
        error("Count not parse value: " + value);
        result = null;
      }
    }

    return result;
  }
Пример #3
0
  private static boolean number(Text t, DataType requiredType, List<Object> valueList) {
    // posNumber
    // : cardinality
    // | '0b' BinaryDigits+ [zZ]?
    // | '0x' HexDigit+ [zZ]?
    // | '-'? Pint? ( '.' Digit+ ) ('e' Pint) [fF]
    // | '-'? Pint [zZfF]?
    // ;
    final boolean result;

    assert !t.isEof() : "Should have been checked by caller";

    if (binary(t, valueList, requiredType) || hex(t, valueList, requiredType)) {
      // ?todo I could allow negatives here
      // ( binary | hex | '0' )
      result = true;
    } else {
      // ( Int DecPart | Int | DecPart ) ( 'e' Int )? [zZfF]?

      final int start = t.cursor();

      if ((t.consumeInt() && (decPart(t) || true) && (exponent(t) || true))
          || (t.consume('-') || true) && decPart(t) && (exponent(t) || true)) {
        final String string = t.getString(start);
        final Object value = deriveType(string, requiredType, t, 10);
        valueList.add(value);
        result = true;
      } else {
        result = false;
      }
    }
    return result;
  }
Пример #4
0
  /**
   * Given the parsing context and what numerical data type is expected convert a string to the
   * correct type. Note no attempt is made to let the magnitude of the number influence our choice.
   *
   * @param string The string to convert to a number. E.g. "123.3e2". If it contains a '.' or an 'e'
   *     then the type must either be f or F.
   * @param requiredType Either z, Z, f, F or any.
   * @param tb The source. The cursor will be at the end of the number but any type specifier will
   *     not have been consumed. If there is one then we'll eat it.
   * @return The derived type.
   * @throws ParsingException If there is a clash of types.
   */
  private static Object deriveType(String string, DataType requiredType, Text t, int radix) {
    final Object result;

    // Figure out the correct type...
    final DataType derivedType;
    if (t.isEof()) {
      if (requiredType == DataType.any) {
        if (string.indexOf('.') >= 0 || string.indexOf('e') >= 0) {
          derivedType = DataType.f;
        } else {
          derivedType = DataType.z;
        }
      } else {
        derivedType = requiredType;
      }
    } else {
      final char c = t.peek();
      if (c == 'z' || c == 'Z' || c == 'f' || c == 'F') {
        t.consume(c);
        derivedType = DataType.valueOf(String.valueOf(c));
        if (!(requiredType == DataType.any || requiredType == derivedType)) {
          throw new ParsingException("Incompatible type: " + string + c);
        }
      } else {
        if (requiredType == DataType.any) {
          if (string.indexOf('.') >= 0 || string.indexOf('e') >= 0) {
            derivedType = DataType.f;
          } else {
            derivedType = DataType.z;
          }
        } else {
          derivedType = requiredType;
        }
      }
    }

    switch (derivedType) {
      case z:
        result = new Long(Long.parseLong(string, radix));
        break;
      case Z:
        result = new BigInteger(string, radix);
        break;
      case f:
        result = new Double(string);
        break;
      case F:
        result = new BigDecimal(string);
        break;
        // $CASES-OMITTED$
      default:
        throw new UnexpectedException("toType: " + derivedType);
    }

    return result;
  }
Пример #5
0
  /**
   * Parse a string into a list of data values. White space is supported only in between the [square
   * brackets].
   *
   * @param string A string representation of an Oak property array, e.g. [ true, null, false ]
   * @param type The type of the array, may be 'any'.
   * @return A potentially empty but not null list of values.
   */
  @SuppressWarnings("unchecked")
  public static <T> List<T> parseArray(String string, DataType type) {
    final List<?> result;

    final Text t = new Text();
    t.append(string);
    if (t.consume('[')
        && (result = elementList(t, type)) != null
        && (t.ws() && t.consume(']'))
        && t.isEof()) {
      // OK
    } else {
      throw new ParsingException("Invalid array: " + string);
    }

    return (List<T>) result;
  }