/** @return 0: normal {n,m}, 2: fixed {n} !introduce returnCode here */ private int fetchRangeQuantifier() { mark(); final boolean synAllow = syntax.allowInvalidInterval(); if (!left()) { if (synAllow) { return 1; /* "....{" : OK! */ } throw new SyntaxException(ERR_END_PATTERN_AT_LEFT_BRACE); } if (!synAllow) { c = peek(); if (c == ')' || c == '(' || c == '|') { throw new SyntaxException(ERR_END_PATTERN_AT_LEFT_BRACE); } } int low = scanUnsignedNumber(); if (low < 0) { throw new SyntaxException(ErrorMessages.ERR_TOO_BIG_NUMBER_FOR_REPEAT_RANGE); } if (low > Config.MAX_REPEAT_NUM) { throw new SyntaxException(ErrorMessages.ERR_TOO_BIG_NUMBER_FOR_REPEAT_RANGE); } boolean nonLow = false; if (p == _p) { /* can't read low */ if (syntax.allowIntervalLowAbbrev()) { low = 0; nonLow = true; } else { return invalidRangeQuantifier(synAllow); } } if (!left()) { return invalidRangeQuantifier(synAllow); } fetch(); int up; int ret = 0; if (c == ',') { final int prev = p; // ??? last up = scanUnsignedNumber(); if (up < 0) { throw new ValueException(ERR_TOO_BIG_NUMBER_FOR_REPEAT_RANGE); } if (up > Config.MAX_REPEAT_NUM) { throw new ValueException(ERR_TOO_BIG_NUMBER_FOR_REPEAT_RANGE); } if (p == prev) { if (nonLow) { return invalidRangeQuantifier(synAllow); } up = QuantifierNode.REPEAT_INFINITE; /* {n,} : {n,infinite} */ } } else { if (nonLow) { return invalidRangeQuantifier(synAllow); } unfetch(); up = low; /* {n} : exact n times */ ret = 2; /* fixed */ } if (!left()) { return invalidRangeQuantifier(synAllow); } fetch(); if (syntax.opEscBraceInterval()) { if (c != syntax.metaCharTable.esc) { return invalidRangeQuantifier(synAllow); } fetch(); } if (c != '}') { return invalidRangeQuantifier(synAllow); } if (!isRepeatInfinite(up) && low > up) { throw new ValueException(ERR_UPPER_SMALLER_THAN_LOWER_IN_REPEAT_RANGE); } token.type = TokenType.INTERVAL; token.setRepeatLower(low); token.setRepeatUpper(up); return ret; /* 0: normal {n,m}, 2: fixed {n} */ }