?? nativeregexp.java
字號:
int start = state.cp; char[] src = state.cpbegin; int value = c - '0'; for (; state.cp != state.cpend; ++state.cp) { c = src[state.cp]; if (!isDigit(c)) { break; } if (!overflow) { int digit = c - '0'; if (value < (maxValue - digit) / 10) { value = value * 10 + digit; } else { overflow = true; value = maxValue; } } } if (overflow) { reportError(overflowMessageId, String.valueOf(src, start, state.cp - start)); } return value; } private static boolean parseTerm(CompilerState state) { char[] src = state.cpbegin; char c = src[state.cp++]; int nDigits = 2; int parenBaseCount = state.parenCount; int num, tmp; RENode term; int termStart; int ocp = state.cp; switch (c) { /* assertions and atoms */ case '^': state.result = new RENode(REOP_BOL); state.progLength++; return true; case '$': state.result = new RENode(REOP_EOL); state.progLength++; return true; case '\\': if (state.cp < state.cpend) { c = src[state.cp++]; switch (c) { /* assertion escapes */ case 'b' : state.result = new RENode(REOP_WBDRY); state.progLength++; return true; case 'B': state.result = new RENode(REOP_WNONBDRY); state.progLength++; return true; /* Decimal escape */ case '0':/* * Under 'strict' ECMA 3, we interpret \0 as NUL and don't accept octal. * However, (XXX and since Rhino doesn't have a 'strict' mode) we'll just * behave the old way for compatibility reasons. * (see http://bugzilla.mozilla.org/show_bug.cgi?id=141078) * */ /* octal escape */ num = 0; while (state.cp < state.cpend) { c = src[state.cp]; if ((c >= '0') && (c <= '7')) { state.cp++; tmp = 8 * num + (c - '0'); if (tmp > 0377) break; num = tmp; } else break; } c = (char)(num); doFlat(state, c); break; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': termStart = state.cp - 1; num = getDecimalValue(c, state, 0xFFFF, "msg.overlarge.backref"); /* * n > 9 and > count of parentheses, * then treat as octal instead. */ if ((num > 9) && (num > state.parenCount)) { state.cp = termStart; num = 0; while (state.cp < state.cpend) { c = src[state.cp]; if ((c >= '0') && (c <= '7')) { state.cp++; tmp = 8 * num + (c - '0'); if (tmp > 0377) break; num = tmp; } else break; } c = (char)(num); doFlat(state, c); break; } /* otherwise, it's a back-reference */ state.result = new RENode(REOP_BACKREF); state.result.parenIndex = num - 1; state.progLength += 3; break; /* Control escape */ case 'f': c = 0xC; doFlat(state, c); break; case 'n': c = 0xA; doFlat(state, c); break; case 'r': c = 0xD; doFlat(state, c); break; case 't': c = 0x9; doFlat(state, c); break; case 'v': c = 0xB; doFlat(state, c); break; /* Control letter */ case 'c': if (((state.cp + 1) < state.cpend) && Character.isLetter(src[state.cp + 1])) c = (char)(src[state.cp++] & 0x1F); else { /* back off to accepting the original '\' as a literal */ --state.cp; c = '\\'; } doFlat(state, c); break; /* UnicodeEscapeSequence */ case 'u': nDigits += 2; // fall thru... /* HexEscapeSequence */ case 'x': { int n = 0; int i; for (i = 0; (i < nDigits) && (state.cp < state.cpend); i++) { int digit; c = src[state.cp++]; n = Kit.xDigitToInt(c, n); if (n < 0) { // Back off to accepting the original // 'u' or 'x' as a literal state.cp -= (i + 2); n = src[state.cp++]; break; } } c = (char)(n); } doFlat(state, c); break; /* Character class escapes */ case 'd': state.result = new RENode(REOP_DIGIT); state.progLength++; break; case 'D': state.result = new RENode(REOP_NONDIGIT); state.progLength++; break; case 's': state.result = new RENode(REOP_SPACE); state.progLength++; break; case 'S': state.result = new RENode(REOP_NONSPACE); state.progLength++; break; case 'w': state.result = new RENode(REOP_ALNUM); state.progLength++; break; case 'W': state.result = new RENode(REOP_NONALNUM); state.progLength++; break; /* IdentityEscape */ default: state.result = new RENode(REOP_FLAT); state.result.chr = c; state.result.length = 1; state.result.flatIndex = state.cp - 1; state.progLength += 3; break; } break; } else { /* a trailing '\' is an error */ reportError("msg.trail.backslash", ""); return false; } case '(': { RENode result = null; termStart = state.cp; if (state.cp + 1 < state.cpend && src[state.cp] == '?' && ((c = src[state.cp + 1]) == '=' || c == '!' || c == ':')) { state.cp += 2; if (c == '=') { result = new RENode(REOP_ASSERT); /* ASSERT, <next>, ... ASSERTTEST */ state.progLength += 4; } else if (c == '!') { result = new RENode(REOP_ASSERT_NOT); /* ASSERTNOT, <next>, ... ASSERTNOTTEST */ state.progLength += 4; } } else { result = new RENode(REOP_LPAREN); /* LPAREN, <index>, ... RPAREN, <index> */ state.progLength += 6; result.parenIndex = state.parenCount++; } ++state.parenNesting; if (!parseDisjunction(state)) return false; if (state.cp == state.cpend || src[state.cp] != ')') { reportError("msg.unterm.paren", ""); return false; } ++state.cp; --state.parenNesting; if (result != null) { result.kid = state.result; state.result = result; } break; } case ')': reportError("msg.re.unmatched.right.paren", ""); return false; case '[': state.result = new RENode(REOP_CLASS); termStart = state.cp; state.result.startIndex = termStart; while (true) { if (state.cp == state.cpend) { reportError("msg.unterm.class", ""); return false; } if (src[state.cp] == '\\') state.cp++; else { if (src[state.cp] == ']') { state.result.kidlen = state.cp - termStart; break; } } state.cp++; } state.result.index = state.classCount++; /* * Call calculateBitmapSize now as we want any errors it finds * to be reported during the parse phase, not at execution. */ if (!calculateBitmapSize(state, state.result, src, termStart, state.cp++)) return false; state.progLength += 3; /* CLASS, <index> */ break; case '.': state.result = new RENode(REOP_DOT); state.progLength++; break; case '*': case '+': case '?': reportError("msg.bad.quant", String.valueOf(src[state.cp - 1])); return false; default: state.result = new RENode(REOP_FLAT); state.result.chr = c; state.result.length = 1; state.result.flatIndex = state.cp - 1; state.progLength += 3; break; } term = state.result; if (state.cp == state.cpend) { return true; } boolean hasQ = false; switch (src[state.cp]) { case '+': state.result = new RENode(REOP_QUANT); state.result.min = 1; state.result.max = -1; /* <PLUS>, <parencount>, <parenindex>, <next> ... <ENDCHILD> */ state.progLength += 8; hasQ = true; break; case '*': state.result = new RENode(REOP_QUANT); state.result.min = 0; state.result.max = -1; /* <STAR>, <parencount>, <parenindex>, <next> ... <ENDCHILD> */ state.progLength += 8; hasQ = true; break; case '?': state.result = new RENode(REOP_QUANT); state.result.min = 0; state.result.max = 1; /* <OPT>, <parencount>, <parenindex>, <next> ... <ENDCHILD> */ state.progLength += 8; hasQ = true; break; case '{': /* balance '}' */ { int min = 0; int max = -1; int leftCurl = state.cp; /* For Perl etc. compatibility, if quntifier does not match * \{\d+(,\d*)?\} exactly back off from it * being a quantifier, and chew it up as a literal * atom next time instead. */ c = src[++state.cp];
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -