⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nativeregexp.java

📁 java中比较著名的js引擎当属mozilla开源的rhino
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
                /* <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];                if (isDigit(c)) {                    ++state.cp;                    min = getDecimalValue(c, state, 0xFFFF,                                          "msg.overlarge.min");                    c = src[state.cp];                    if (c == ',') {                        c = src[++state.cp];                        if (isDigit(c)) {                            ++state.cp;                            max = getDecimalValue(c, state, 0xFFFF,                                                  "msg.overlarge.max");                            c = src[state.cp];                            if (min > max) {                                reportError("msg.max.lt.min",                                            String.valueOf(src[state.cp]));                                return false;                            }                        }                    } else {                        max = min;                    }                    /* balance '{' */                    if (c == '}') {                        state.result = new RENode(REOP_QUANT);                        state.result.min = min;                        state.result.max = max;                        // QUANT, <min>, <max>, <parencount>,                        // <parenindex>, <next> ... <ENDCHILD>                        state.progLength += 12;                        hasQ = true;                    }                }                if (!hasQ) {                    state.cp = leftCurl;                }                break;            }        }        if (!hasQ)            return true;        ++state.cp;        state.result.kid = term;        state.result.parenIndex = parenBaseCount;        state.result.parenCount = state.parenCount - parenBaseCount;        if ((state.cp < state.cpend) && (src[state.cp] == '?')) {            ++state.cp;            state.result.greedy = false;        }        else            state.result.greedy = true;        return true;    }    private static void resolveForwardJump(byte[] array, int from, int pc)    {        if (from > pc) throw Kit.codeBug();        addIndex(array, from, pc - from);    }    private static int getOffset(byte[] array, int pc)    {        return getIndex(array, pc);    }    private static int addIndex(byte[] array, int pc, int index)    {        if (index < 0) throw Kit.codeBug();        if (index > 0xFFFF)            throw Context.reportRuntimeError("Too complex regexp");        array[pc] = (byte)(index >> 8);        array[pc + 1] = (byte)(index);        return pc + 2;    }    private static int getIndex(byte[] array, int pc)    {        return ((array[pc] & 0xFF) << 8) | (array[pc + 1] & 0xFF);    }    private static final int OFFSET_LEN = 2;    private static final int INDEX_LEN  = 2;    private static int    emitREBytecode(CompilerState state, RECompiled re, int pc, RENode t)    {        RENode nextAlt;        int nextAltFixup, nextTermFixup;        byte[] program = re.program;        while (t != null) {            program[pc++] = t.op;            switch (t.op) {            case REOP_EMPTY:                --pc;                break;            case REOP_ALT:                nextAlt = t.kid2;                nextAltFixup = pc;    /* address of next alternate */                pc += OFFSET_LEN;                pc = emitREBytecode(state, re, pc, t.kid);                program[pc++] = REOP_JUMP;                nextTermFixup = pc;    /* address of following term */                pc += OFFSET_LEN;                resolveForwardJump(program, nextAltFixup, pc);                pc = emitREBytecode(state, re, pc, nextAlt);                program[pc++] = REOP_JUMP;                nextAltFixup = pc;                pc += OFFSET_LEN;                resolveForwardJump(program, nextTermFixup, pc);                resolveForwardJump(program, nextAltFixup, pc);                break;            case REOP_FLAT:                /*                 * Consecutize FLAT's if possible.                 */                if (t.flatIndex != -1) {                    while ((t.next != null) && (t.next.op == REOP_FLAT)                            && ((t.flatIndex + t.length)                                            == t.next.flatIndex)) {                        t.length += t.next.length;                        t.next = t.next.next;                    }                }                if ((t.flatIndex != -1) && (t.length > 1)) {                    if ((state.flags & JSREG_FOLD) != 0)                        program[pc - 1] = REOP_FLATi;                    else                        program[pc - 1] = REOP_FLAT;                    pc = addIndex(program, pc, t.flatIndex);                    pc = addIndex(program, pc, t.length);                }                else {                    if (t.chr < 256) {                        if ((state.flags & JSREG_FOLD) != 0)                            program[pc - 1] = REOP_FLAT1i;                        else                            program[pc - 1] = REOP_FLAT1;                        program[pc++] = (byte)(t.chr);                    }                    else {                        if ((state.flags & JSREG_FOLD) != 0)                            program[pc - 1] = REOP_UCFLAT1i;                        else                            program[pc - 1] = REOP_UCFLAT1;                        pc = addIndex(program, pc, t.chr);                    }                }                break;            case REOP_LPAREN:                pc = addIndex(program, pc, t.parenIndex);                pc = emitREBytecode(state, re, pc, t.kid);                program[pc++] = REOP_RPAREN;                pc = addIndex(program, pc, t.parenIndex);                break;            case REOP_BACKREF:                pc = addIndex(program, pc, t.parenIndex);                break;            case REOP_ASSERT:                nextTermFixup = pc;                pc += OFFSET_LEN;                pc = emitREBytecode(state, re, pc, t.kid);                program[pc++] = REOP_ASSERTTEST;                resolveForwardJump(program, nextTermFixup, pc);                break;            case REOP_ASSERT_NOT:                nextTermFixup = pc;                pc += OFFSET_LEN;                pc = emitREBytecode(state, re, pc, t.kid);                program[pc++] = REOP_ASSERTNOTTEST;                resolveForwardJump(program, nextTermFixup, pc);                break;            case REOP_QUANT:                if ((t.min == 0) && (t.max == -1))                    program[pc - 1] = (t.greedy) ? REOP_STAR : REOP_MINIMALSTAR;                else                if ((t.min == 0) && (t.max == 1))                    program[pc - 1] = (t.greedy) ? REOP_OPT : REOP_MINIMALOPT;                else                if ((t.min == 1) && (t.max == -1))                    program[pc - 1] = (t.greedy) ? REOP_PLUS : REOP_MINIMALPLUS;                else {                    if (!t.greedy) program[pc - 1] = REOP_MINIMALQUANT;                    pc = addIndex(program, pc, t.min);                    // max can be -1 which addIndex does not accept                    pc = addIndex(program, pc, t.max + 1);                }                pc = addIndex(program, pc, t.parenCount);                pc = addIndex(program, pc, t.parenIndex);                nextTermFixup = pc;                pc += OFFSET_LEN;                pc = emitREBytecode(state, re, pc, t.kid);                program[pc++] = REOP_ENDCHILD;                resolveForwardJump(program, nextTermFixup, pc);                break;            case REOP_CLASS:                pc = addIndex(program, pc, t.index);                re.classList[t.index] = new RECharSet(t.bmsize, t.startIndex,                                                      t.kidlen);                break;            default:                break;            }            t = t.next;        }        return pc;    }    private static void    pushProgState(REGlobalData gData, int min, int max,                  REBackTrackData backTrackLastToSave,                  int continuation_pc, int continuation_op)    {        gData.stateStackTop = new REProgState(gData.stateStackTop, min, max,                                              gData.cp, backTrackLastToSave,                                              continuation_pc,                                              continuation_op);    }    private static REProgState    popProgState(REGlobalData gData)    {        REProgState state = gData.stateStackTop;        gData.stateStackTop = state.previous;        return state;    }    private static void    pushBackTrackState(REGlobalData gData, byte op, int target)    {        gData.backTrackStackTop = new REBackTrackData(gData, op, target);    }    /*     *   Consecutive literal characters.     */    private static boolean    flatNMatcher(REGlobalData gData, int matchChars,                 int length, char[] chars, int end)    {        if ((gData.cp + length) > end)            return false;        for (int i = 0; i < length; i++) {            if (gData.regexp.source[matchChars + i] != chars[gData.cp + i]) {                return false;            }        }        gData.cp += length;        return true;    }    private static boolean    flatNIMatcher(REGlobalData gData, int matchChars,                  int length, char[] chars, int end)    {        if ((gData.cp + length) > end)            return false;        for (int i = 0; i < length; i++) {            if (upcase(gData.regexp.source[matchChars + i])                != upcase(chars[gData.cp + i]))            {                return false;            }        }        gData.cp += length;        return true;    }    /*    1. Evaluate DecimalEscape to obtain an EscapeValue E.    2. If E is not a character then go to step 6.    3. Let ch be E's character.    4. Let A be a one-element RECharSet containing the character ch.    5. Call CharacterSetMatcher(A, false) and return its Matcher result.    6. E must be an integer. Let n be that integer.    7. If n=0 or n>NCapturingParens then throw a SyntaxError exception.    8. Return an internal Matcher closure that takes two arguments, a State x       and a Continuation c, and performs the following:        1. Let cap be x's captures internal array.        2. Let s be cap[n].        3. If s is undefined, then call c(x) and return its result.        4. Let e be x's endIndex.        5. Let len be s's length.        6. Let f be e+len.        7. If f>InputLength, return failure.        8. If there exists an integer i between 0 (inclusive) and len (exclusive)           such that Canonicalize(s[i]) is not the same character as           Canonicalize(Input [e+i]), then return failure.        9. Let y be the State (f, cap).        10. Call c(y) and return its result.    */    private static boolean    backrefMatcher(REGlobalData gData, int parenIndex,                   char[] chars, int end)    {        int len;        int i;        int parenContent = gData.parens_index(parenIndex);        if (parenContent == -1)            return true;        len = gData.parens_length(parenIndex);        if ((gData.cp + len) > end)            return false;        if ((gData.regexp.flags & JSREG_FOLD) != 0) {            for (i = 0; i < len; i++) {                if (upcase(chars[parenContent + i]) != upcase(chars[gData.cp + i]))                    return false;            }        }        else {            for (i = 0; i < len; i++) {                if (chars[parenContent + i] != chars[gData.cp + i])                    return false;            }        }        gData.cp += len;        return true;    }    /* Add a single character to the RECharSet */    private static void    addCharacterToCharSet(RECharSet cs, char c)    {        int byteIndex = (int)(c / 8);        if (c > cs.length)            throw new RuntimeException();        cs.bits[byteIndex] |= 1 << (c & 0x7);    }    /* Add a character range, c1 to c2 (inclusive) to the RECharSet */    private static void    addCharacterRangeToCharSet(RECharSet cs, char c1, char c2)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -