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

📄 regexpimpl.java

📁 java中比较著名的js引擎当属mozilla开源的rhino
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
    /**     * Analog of REGEXP_PAREN_SUBSTRING in C jsregexp.h.     * Assumes zero-based; i.e., for $3, i==2     */    SubString getParenSubString(int i)    {        if (parens != null && i < parens.length) {            SubString parsub = parens[i];            if (parsub != null) {                return parsub;            }        }        return SubString.emptySubString;    }    /*     * Analog of match_glob() in jsstr.c     */    private static void match_glob(GlobData mdata, Context cx,                                   Scriptable scope, int count,                                   RegExpImpl reImpl)    {        if (mdata.arrayobj == null) {            Scriptable s = ScriptableObject.getTopLevelScope(scope);            mdata.arrayobj = ScriptRuntime.newObject(cx, s, "Array", null);        }        SubString matchsub = reImpl.lastMatch;        String matchstr = matchsub.toString();        mdata.arrayobj.put(count, mdata.arrayobj, matchstr);    }    /*     * Analog of replace_glob() in jsstr.c     */    private static void replace_glob(GlobData rdata, Context cx,                                     Scriptable scope, RegExpImpl reImpl,                                     int leftIndex, int leftlen)    {        int replen;        String lambdaStr;        if (rdata.lambda != null) {            // invoke lambda function with args lastMatch, $1, $2, ... $n,            // leftContext.length, whole string.            SubString[] parens = reImpl.parens;            int parenCount = (parens == null) ? 0 : parens.length;            Object[] args = new Object[parenCount + 3];            args[0] = reImpl.lastMatch.toString();            for (int i=0; i < parenCount; i++) {                SubString sub = parens[i];                if (sub != null) {                    args[i+1] = sub.toString();                } else {                    args[i+1] = Undefined.instance;                }            }            args[parenCount+1] = new Integer(reImpl.leftContext.length);            args[parenCount+2] = rdata.str;            // This is a hack to prevent expose of reImpl data to            // JS function which can run new regexps modifing            // regexp that are used later by the engine.            // TODO: redesign is necessary            if (reImpl != ScriptRuntime.getRegExpProxy(cx)) Kit.codeBug();            RegExpImpl re2 = new RegExpImpl();            re2.multiline = reImpl.multiline;            re2.input = reImpl.input;            ScriptRuntime.setRegExpProxy(cx, re2);            try {                Scriptable parent = ScriptableObject.getTopLevelScope(scope);                Object result = rdata.lambda.call(cx, parent, parent, args);                lambdaStr = ScriptRuntime.toString(result);            } finally {                ScriptRuntime.setRegExpProxy(cx, reImpl);            }            replen = lambdaStr.length();        } else {            lambdaStr = null;            replen = rdata.repstr.length();            if (rdata.dollar >= 0) {                int[] skip = new int[1];                int dp = rdata.dollar;                do {                    SubString sub = interpretDollar(cx, reImpl, rdata.repstr,                                                    dp, skip);                    if (sub != null) {                        replen += sub.length - skip[0];                        dp += skip[0];                    } else {                        ++dp;                    }                    dp = rdata.repstr.indexOf('$', dp);                } while (dp >= 0);            }        }        int growth = leftlen + replen + reImpl.rightContext.length;        StringBuffer charBuf = rdata.charBuf;        if (charBuf == null) {            charBuf = new StringBuffer(growth);            rdata.charBuf = charBuf;        } else {            charBuf.ensureCapacity(rdata.charBuf.length() + growth);        }        charBuf.append(reImpl.leftContext.charArray, leftIndex, leftlen);        if (rdata.lambda != null) {            charBuf.append(lambdaStr);        } else {            do_replace(rdata, cx, reImpl);        }    }    private static SubString interpretDollar(Context cx, RegExpImpl res,                                             String da, int dp, int[] skip)    {        char dc;        int num, tmp;        if (da.charAt(dp) != '$') Kit.codeBug();        /* Allow a real backslash (literal "\\") to escape "$1" etc. */        int version = cx.getLanguageVersion();        if (version != Context.VERSION_DEFAULT            && version <= Context.VERSION_1_4)        {            if (dp > 0 && da.charAt(dp - 1) == '\\')                return null;        }        int daL = da.length();        if (dp + 1 >= daL)            return null;        /* Interpret all Perl match-induced dollar variables. */        dc = da.charAt(dp + 1);        if (NativeRegExp.isDigit(dc)) {            int cp;            if (version != Context.VERSION_DEFAULT                && version <= Context.VERSION_1_4)            {                if (dc == '0')                    return null;                /* Check for overflow to avoid gobbling arbitrary decimal digits. */                num = 0;                cp = dp;                while (++cp < daL && NativeRegExp.isDigit(dc = da.charAt(cp)))                {                    tmp = 10 * num + (dc - '0');                    if (tmp < num)                        break;                    num = tmp;                }            }            else {  /* ECMA 3, 1-9 or 01-99 */                int parenCount = (res.parens == null) ? 0 : res.parens.length;                num = dc - '0';                if (num > parenCount)                    return null;                cp = dp + 2;                if ((dp + 2) < daL) {                    dc = da.charAt(dp + 2);                    if (NativeRegExp.isDigit(dc)) {                        tmp = 10 * num + (dc - '0');                        if (tmp <= parenCount) {                            cp++;                            num = tmp;                        }                    }                }                if (num == 0) return null;  /* $0 or $00 is not valid */            }            /* Adjust num from 1 $n-origin to 0 array-index-origin. */            num--;            skip[0] = cp - dp;            return res.getParenSubString(num);        }        skip[0] = 2;        switch (dc) {          case '$':            return new SubString("$");          case '&':            return res.lastMatch;          case '+':            return res.lastParen;          case '`':            if (version == Context.VERSION_1_2) {                /*                 * JS1.2 imitated the Perl4 bug where left context at each step                 * in an iterative use of a global regexp started from last match,                 * not from the start of the target string.  But Perl4 does start                 * $` at the beginning of the target string when it is used in a                 * substitution, so we emulate that special case here.                 */                res.leftContext.index = 0;                res.leftContext.length = res.lastMatch.index;            }            return res.leftContext;          case '\'':            return res.rightContext;        }        return null;    }    /**     * Analog of do_replace in jsstr.c     */    private static void do_replace(GlobData rdata, Context cx,                                   RegExpImpl regExpImpl)    {        StringBuffer charBuf = rdata.charBuf;        int cp = 0;        String da = rdata.repstr;        int dp = rdata.dollar;        if (dp != -1) {            int[] skip = new int[1];            do {                int len = dp - cp;                charBuf.append(da.substring(cp, dp));                cp = dp;                SubString sub = interpretDollar(cx, regExpImpl, da,                                                dp, skip);                if (sub != null) {                    len = sub.length;                    if (len > 0) {                        charBuf.append(sub.charArray, sub.index, len);                    }                    cp += skip[0];                    dp += skip[0];                } else {                    ++dp;                }                dp = da.indexOf('$', dp);            } while (dp >= 0);        }        int daL = da.length();        if (daL > cp) {            charBuf.append(da.substring(cp, daL));        }    }    String          input;         /* input string to match (perl $_, GC root) */    boolean         multiline;     /* whether input contains newlines (perl $*) */    SubString[]     parens;        /* Vector of SubString; last set of parens                                      matched (perl $1, $2) */    SubString       lastMatch;     /* last string matched (perl $&) */    SubString       lastParen;     /* last paren matched (perl $+) */    SubString       leftContext;   /* input to left of last match (perl $`) */    SubString       rightContext;  /* input to right of last match (perl $') */}final class GlobData{    int      mode;      /* input: return index, match object, or void */    int      optarg;    /* input: index of optional flags argument */    boolean  global;    /* output: whether regexp was global */    String   str;       /* output: 'this' parameter object as string */    NativeRegExp regexp;/* output: regexp parameter object private data */    // match-specific data    Scriptable arrayobj;    // replace-specific data    Function      lambda;        /* replacement function object or null */    String        repstr;        /* replacement string */    int           dollar = -1;   /* -1 or index of first $ in repstr */    StringBuffer  charBuf;       /* result characters, null initially */    int           leftIndex;     /* leftContext index, always 0 for JS1.2 */}

⌨️ 快捷键说明

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