예제 #1
0
파일: DataType.java 프로젝트: inexas/oak
  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;
  }
예제 #2
0
파일: DataType.java 프로젝트: inexas/oak
  private static boolean text(Text t, List<Object> valueList) {
    final boolean result;

    final int start = t.cursor();
    if (t.consumeString()) {
      // +/- 1s: drop the quotes
      final String textValue = unescape(t, start + 1, t.cursor() - 1);
      valueList.add(textValue);
      result = true;
    } else {
      // ?todo Could easily detect unterminated string and throw here
      result = false;
    }

    return result;
  }
예제 #3
0
파일: DataType.java 프로젝트: inexas/oak
  private static boolean decPart(Text t) {
    final boolean result;

    // '.' Digits+
    final int save = t.cursor();
    if (t.consume('.') && t.consumeAscii(Text.ASCII_0_9)) {
      result = true;
    } else {
      t.setCursor(save);
      result = false;
    }

    return result;
  }
예제 #4
0
파일: DataType.java 프로젝트: inexas/oak
  private static boolean exponent(Text t) {
    final boolean result;

    // 'e' Int
    final int save = t.cursor();
    if (t.consume('e') && t.consumeInt()) {
      result = true;
    } else {
      t.setCursor(save);
      result = false;
    }

    return result;
  }
예제 #5
0
파일: DataType.java 프로젝트: inexas/oak
  private static boolean identifier(Text t, List<Object> valueList) {
    final boolean result;

    final int start = t.cursor();
    if (Identifier.consume(t)) {
      final String string = t.getString(start);
      valueList.add(new Identifier(string));
      result = true;
    } else {
      result = false;
    }

    return result;
  }
예제 #6
0
파일: DataType.java 프로젝트: inexas/oak
  private static boolean time(Text t) {
    final boolean result;

    // HH ':' mm ( : ss )?

    // Try for HH:mm...
    int reset = t.cursor();
    if (t.consumeAscii(Text.ASCII_0_9) && t.consume(':') && t.consumeAscii(Text.ASCII_0_9)) {
      result = true;
      reset = t.cursor();

      // Try for :ss...
      if (t.consume(':') && t.consumeAscii(Text.ASCII_0_9)) {
        reset = t.cursor();
      }
    } else {
      result = false;
    }

    t.setCursor(reset);

    return result;
  }
예제 #7
0
파일: DataType.java 프로젝트: inexas/oak
  private static boolean date(Text t, List<Object> valueList) {
    final boolean result;

    final int start = t.cursor();
    if (t.consume('@') && date(t)) {
      final String string = t.getString(start + 1); // Jump the'@'
      final LocalDate value = DateU.parseStandardDate(string);
      valueList.add(value);
      result = true;
    } else {
      result = false;
    }

    return result;
  }
예제 #8
0
파일: DataType.java 프로젝트: inexas/oak
  /**
   * There's a bug in this as it requires seconds in the string whereas the time() function does
   * not. It seems to be in the Java parser.
   *
   * @param tb Source to parse.
   * @return A Temporal or null if none found.
   */
  @Nullable
  private static Temporal temporal(Text t) {
    Temporal result;

    final int save = t.cursor();
    t.consume('@');
    final int start = save + 1;

    // yyyy/MM/dd HH:mm:ss

    try {
      if (date(t)) {
        final int save2 = t.cursor();
        t.ws();
        if (time(t)) {
          final String string = t.getString(start);
          result = DateU.parseStandardDatetime(string);
        } else {
          t.setCursor(save2);
          final String string = t.getString(start);
          result = DateU.parseStandardDate(string);
        }
      } else if (time(t)) {
        final String string = t.getString(start);
        result = DateU.parseStandardTime(string);
      } else {
        result = null;
        t.setCursor(save);
      }
    } catch (final DateTimeParseException e) {
      result = null;
      t.setCursor(save);
    }

    return result;
  }
예제 #9
0
파일: DataType.java 프로젝트: inexas/oak
  private static List<Object> elementList(Text t, DataType type) {
    final List<Object> result = new ArrayList<>();

    // elementList: ( WS? value ( WS? ',' WS? value )* WS? )?
    if (t.ws() && value(t, type, result)) {
      while (true) {
        final int save = t.cursor();
        if (t.ws() && t.consume(',') && t.ws() && value(t, type, result)) {
          continue;
        }
        t.setCursor(save);
        break;
      }
    }

    return result;
  }
예제 #10
0
파일: DataType.java 프로젝트: inexas/oak
  private static boolean binary(Text t, List<Object> valueList, DataType requiredType) {
    final boolean result;

    // '0b' [01]+ [zZfF]?
    final int save = t.cursor();
    if (t.consume("0b") && t.consumeAscii(Text.ASCII_0_1)) {
      final String string = t.getString(save + 2);
      final Object value = deriveType(string, requiredType, t, 2);
      valueList.add(value);
      result = true;
    } else {
      t.setCursor(save);
      result = false;
    }

    return result;
  }
예제 #11
0
파일: DataType.java 프로젝트: inexas/oak
  private static boolean date(Text t) {
    final boolean result;

    // yyyy '/' MM '/' dd

    final int save = t.cursor();
    if (t.consumeAscii(Text.ASCII_0_9)
        && t.consume('/')
        && t.consumeAscii(Text.ASCII_0_9)
        && t.consume('/')
        && t.consumeAscii(Text.ASCII_0_9)) {
      result = true;
    } else {
      result = false;
      t.setCursor(save);
    }

    return result;
  }
예제 #12
0
파일: DataType.java 프로젝트: inexas/oak
  /**
   * In Oak it is possible to embed a tab character as an ASCII 8 or as a \t but internally we store
   * this in ASCII. The same goes for newlines and other tables (see the Oak reference). Here we
   * convert external format to internal format.
   *
   * @param source The text to process, may be null. E.g. "Hello\tworld" (with the quotes)
   * @return Return an internal format string.
   */
  @Nullable
  public static String textToInternalFormat(@Nullable String source) throws ParsingException {
    final String result;

    assert source == null
        || source.length() >= 2
            && source.charAt(0) == '"'
            && source.charAt(source.length() - 1) == '"';

    if (source == null) {
      result = null;
    } else {
      final Text t = new Text();
      final char[] ca = source.toCharArray();
      final int length = ca.length - 1; // 1 because remove quotes

      for (int i = 1; i < length; i++) { // 1 because remove quotes
        final char c = ca[i];
        if (c == '\\') {
          if (i == length - 1) {
            error("Invalid text " + source + ", escape at end of line");
          } else {
            i++;
            final char next = ca[i];
            if (next == 't') {
              t.append('\t');
            } else if (next == 'n') {
              t.append('\n');
            } else if (next == '"') {
              t.append('"');
            } else if (next == '\\') {
              t.append('\\');
            } else if (next == 'u') {
              // Unicode, 1-4 hex characters...
              i++;

              final Text hex = new Text();
              hex.append(source);
              hex.setCursor(i);
              final int start = i;
              if (hex.consumeAscii(Text.ASCII_0_F)) {
                final int end = start + Math.min(4, hex.cursor() - start);
                final String string = hex.getString(start, end);
                final char u = (char) Integer.parseInt(string, 16);
                t.append(u);
                i = end - 1;
              } else {
                error("Invalid text " + source + ", incorrect unicode");
              }
            } else {
              error("Invalid text: \\" + next);
            }
          }
        } else {
          t.append(c);
        }
      }
      result = t.toString();
    }

    return result;
  }