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

📄 jsregexp.c

📁 java script test programing source code
💻 C
📖 第 1 页 / 共 5 页
字号:
    RENode *term;    term = state->result;    if (state->cp < state->cpend) {        switch (*state->cp) {        case '+':            state->result = NewRENode(state, REOP_QUANT);            if (!state->result)                return JS_FALSE;            state->result->u.range.min = 1;            state->result->u.range.max = (uintN)-1;            /* <PLUS>, <next> ... <ENDCHILD> */            state->progLength += 4;            goto quantifier;        case '*':            state->result = NewRENode(state, REOP_QUANT);            if (!state->result)                return JS_FALSE;            state->result->u.range.min = 0;            state->result->u.range.max = (uintN)-1;            /* <STAR>, <next> ... <ENDCHILD> */            state->progLength += 4;            goto quantifier;        case '?':            state->result = NewRENode(state, REOP_QUANT);            if (!state->result)                return JS_FALSE;            state->result->u.range.min = 0;            state->result->u.range.max = 1;            /* <OPT>, <next> ... <ENDCHILD> */            state->progLength += 4;            goto quantifier;        case '{':       /* balance '}' */        {            intN err;            const jschar *errp = state->cp;            err = ParseMinMaxQuantifier(state, JS_FALSE);            if (err == 0)                goto quantifier;            if (err == -1)                return JS_TRUE;            js_ReportCompileErrorNumberUC(state->context,                                          state->tokenStream,                                          JSREPORT_TS | JSREPORT_ERROR,                                          err, errp);            return JS_FALSE;        }        default:;        }    }    return JS_TRUE;quantifier:    if (state->treeDepth == TREE_DEPTH_MAX) {        js_ReportCompileErrorNumber(state->context, state->tokenStream,                                    JSREPORT_TS | JSREPORT_ERROR,                                    JSMSG_REGEXP_TOO_COMPLEX);        return JS_FALSE;    }    ++state->treeDepth;    ++state->cp;    state->result->kid = term;    if (state->cp < state->cpend && *state->cp == '?') {        ++state->cp;        state->result->u.range.greedy = JS_FALSE;    } else {        state->result->u.range.greedy = JS_TRUE;    }    return JS_TRUE;}static intNParseMinMaxQuantifier(CompilerState *state, JSBool ignoreValues){    uintN min, max;    jschar c;    const jschar *errp = state->cp++;    c = *state->cp;    if (JS7_ISDEC(c)) {        ++state->cp;        min = GetDecimalValue(c, 0xFFFF, NULL, state);        c = *state->cp;        if (!ignoreValues && min == OVERFLOW_VALUE)            return JSMSG_MIN_TOO_BIG;        if (c == ',') {            c = *++state->cp;            if (JS7_ISDEC(c)) {                ++state->cp;                max = GetDecimalValue(c, 0xFFFF, NULL, state);                c = *state->cp;                if (!ignoreValues && max == OVERFLOW_VALUE)                    return JSMSG_MAX_TOO_BIG;                if (!ignoreValues && min > max)                    return JSMSG_OUT_OF_ORDER;            } else {                max = (uintN)-1;            }        } else {            max = min;        }        if (c == '}') {            state->result = NewRENode(state, REOP_QUANT);            if (!state->result)                return JS_FALSE;            state->result->u.range.min = min;            state->result->u.range.max = max;            /*             * QUANT, <min>, <max>, <next> ... <ENDCHILD>             * where <max> is written as compact(max+1) to make             * (uintN)-1 sentinel to occupy 1 byte, not width_of(max)+1.             */            state->progLength += (1 + GetCompactIndexWidth(min)                                  + GetCompactIndexWidth(max + 1)                                  +3);            return 0;        }    }    state->cp = errp;    return -1;}static JSBoolSetForwardJumpOffset(jsbytecode *jump, jsbytecode *target){    ptrdiff_t offset = target - jump;    /* Check that target really points forward. */    JS_ASSERT(offset >= 2);    if ((size_t)offset > OFFSET_MAX)        return JS_FALSE;    jump[0] = JUMP_OFFSET_HI(offset);    jump[1] = JUMP_OFFSET_LO(offset);    return JS_TRUE;}/* * Generate bytecode for the tree rooted at t using an explicit stack instead * of recursion. */static jsbytecode *EmitREBytecode(CompilerState *state, JSRegExp *re, size_t treeDepth,               jsbytecode *pc, RENode *t){    EmitStateStackEntry *emitStateSP, *emitStateStack;    RECharSet *charSet;    REOp op;    if (treeDepth == 0) {        emitStateStack = NULL;    } else {        emitStateStack =            (EmitStateStackEntry *)JS_malloc(state->context,                                             sizeof(EmitStateStackEntry) *                                             treeDepth);        if (!emitStateStack)            return NULL;    }    emitStateSP = emitStateStack;    op = t->op;    for (;;) {        *pc++ = op;        switch (op) {        case REOP_EMPTY:            --pc;            break;        case REOP_ALTPREREQ2:        case REOP_ALTPREREQ:            JS_ASSERT(emitStateSP);            emitStateSP->altHead = pc - 1;            emitStateSP->endTermFixup = pc;            pc += OFFSET_LEN;            SET_ARG(pc, t->u.altprereq.ch1);            pc += ARG_LEN;            SET_ARG(pc, t->u.altprereq.ch2);            pc += ARG_LEN;            emitStateSP->nextAltFixup = pc;    /* offset to next alternate */            pc += OFFSET_LEN;            emitStateSP->continueNode = t;            emitStateSP->continueOp = REOP_JUMP;            emitStateSP->jumpToJumpFlag = JS_FALSE;            ++emitStateSP;            JS_ASSERT((size_t)(emitStateSP - emitStateStack) <= treeDepth);            t = (RENode *) t->kid;            op = t->op;            continue;        case REOP_JUMP:            emitStateSP->nextTermFixup = pc;    /* offset to following term */            pc += OFFSET_LEN;            if (!SetForwardJumpOffset(emitStateSP->nextAltFixup, pc))                goto jump_too_big;            emitStateSP->continueOp = REOP_ENDALT;            ++emitStateSP;            JS_ASSERT((size_t)(emitStateSP - emitStateStack) <= treeDepth);            t = t->u.kid2;            op = t->op;            continue;        case REOP_ENDALT:            /*             * If we already patched emitStateSP->nextTermFixup to jump to             * a nearer jump, to avoid 16-bit immediate offset overflow, we             * are done here.             */            if (emitStateSP->jumpToJumpFlag)                break;            /*             * Fix up the REOP_JUMP offset to go to the op after REOP_ENDALT.             * REOP_ENDALT is executed only on successful match of the last             * alternate in a group.             */            if (!SetForwardJumpOffset(emitStateSP->nextTermFixup, pc))                goto jump_too_big;            if (t->op != REOP_ALT) {                if (!SetForwardJumpOffset(emitStateSP->endTermFixup, pc))                    goto jump_too_big;            }            /*             * If the program is bigger than the REOP_JUMP offset range, then             * we must check for alternates before this one that are part of             * the same group, and fix up their jump offsets to target jumps             * close enough to fit in a 16-bit unsigned offset immediate.             */            if ((size_t)(pc - re->program) > OFFSET_MAX &&                emitStateSP > emitStateStack) {                EmitStateStackEntry *esp, *esp2;                jsbytecode *alt, *jump;                ptrdiff_t span, header;                esp2 = emitStateSP;                alt = esp2->altHead;                for (esp = esp2 - 1; esp >= emitStateStack; --esp) {                    if (esp->continueOp == REOP_ENDALT &&                        !esp->jumpToJumpFlag &&                        esp->nextTermFixup + OFFSET_LEN == alt &&                        (size_t)(pc - ((esp->continueNode->op != REOP_ALT)                                       ? esp->endTermFixup                                       : esp->nextTermFixup)) > OFFSET_MAX) {                        alt = esp->altHead;                        jump = esp->nextTermFixup;                        /*                         * The span must be 1 less than the distance from                         * jump offset to jump offset, so we actually jump                         * to a REOP_JUMP bytecode, not to its offset!                         */                        for (;;) {                            JS_ASSERT(jump < esp2->nextTermFixup);                            span = esp2->nextTermFixup - jump - 1;                            if ((size_t)span <= OFFSET_MAX)                                break;                            do {                                if (--esp2 == esp)                                    goto jump_too_big;                            } while (esp2->continueOp != REOP_ENDALT);                        }                        jump[0] = JUMP_OFFSET_HI(span);                        jump[1] = JUMP_OFFSET_LO(span);                        if (esp->continueNode->op != REOP_ALT) {                            /*                             * We must patch the offset at esp->endTermFixup                             * as well, for the REOP_ALTPREREQ{,2} opcodes.                             * If we're unlucky and endTermFixup is more than                             * OFFSET_MAX bytes from its target, we cheat by                             * jumping 6 bytes to the jump whose offset is at                             * esp->nextTermFixup, which has the same target.                             */                            jump = esp->endTermFixup;                            header = esp->nextTermFixup - jump;                            span += header;                            if ((size_t)span > OFFSET_MAX)                                span = header;                            jump[0] = JUMP_OFFSET_HI(span);                            jump[1] = JUMP_OFFSET_LO(span);                        }                        esp->jumpToJumpFlag = JS_TRUE;                    }                }            }            break;        case REOP_ALT:            JS_ASSERT(emitStateSP);            emitStateSP->altHead = pc - 1;            emitStateSP->nextAltFixup = pc;     /* offset to next alternate */            pc += OFFSET_LEN;            emitStateSP->continueNode = t;            emitStateSP->continueOp = REOP_JUMP;            emitStateSP->jumpToJumpFlag = JS_FALSE;            ++emitStateSP;            JS_ASSERT((size_t)(emitStateSP - emitStateStack) <= treeDepth);            t = t->kid;            op = t->op;            continue;        case REOP_FLAT:            /*             * Coalesce FLATs if possible and if it would not increase bytecode             * beyond preallocated limit. The latter happens only when bytecode             * size for coalesced string with offset p and length 2 exceeds 6             * bytes preallocated for 2 single char nodes, i.e. when             * 1 + GetCompactIndexWidth(p) + GetCompactIndexWidth(2) > 6 or             * GetCompactIndexWidth(p) > 4.             * Since when GetCompactIndexWidth(p) <= 4 coalescing of 3 or more             * nodes strictly decreases bytecode size, the check has to be             * done only for the first coalescing.             */            if (t->kid &&                GetCompactIndexWidth((jschar *)t->kid - state->cpbegin) <= 4)            {                while (t->next &&                       t->next->op == REOP_FLAT &&                       (jschar*)t->kid + t->u.flat.length ==                       (jschar*)t->next->kid) {                    t->u.flat.length += t->next->u.flat.length;                    t->next = t->next->next;                }            }            if (t->kid && t->u.flat.length > 1) {                pc[-1] = (state->flags & JSREG_FOLD) ? REOP_FLATi : REOP_FLAT;                pc = WriteCompactIndex(pc, (jschar *)t->kid - state->cpbegin);                pc = WriteCompactIndex(pc, t->u.flat.length);            } else if (t->u.flat.chr < 256) {                pc[-1] = (state->flags & JSREG_FOLD) ? REOP_FLAT1i : REOP_FLAT1;                *pc++ = (jsbytecode) t->u.flat.chr;            } else {                pc[-1] = (state->flags & JSREG_FOLD)                         ? REOP_UCFLAT1i                         : REOP_UCFLAT1;                SET_ARG(pc, t->u.flat.chr);                pc += ARG_LEN;            }            break;        case REOP_LPAREN:            JS_ASSERT(emitStateSP);            pc = WriteCompactIndex(pc, t->u.parenIndex);            emitStateSP->continueNode = t;            emitStateSP->continueOp = REOP_RPAREN;            ++emitStateSP;            JS_ASSERT((size_t)(emitStateSP - e

⌨️ 快捷键说明

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