示例#1
0
        // startCond() returns the leading empty-width conditions that must be true
        // in any match.  It returns -1 (all bits set) if no matches are possible.
        public int startCond()
        {
            int  flag = 0; // bitmask of EMPTY_* flags
            int  pc   = start;
            bool done = false;

            for (;;)
            {
                Inst i = inst[pc];
                switch (i.op)
                {
                case Inst.InstOp.EMPTY_WIDTH:
                    flag |= i.arg;
                    break;

                case Inst.InstOp.FAIL:
                    return(-1);

                case Inst.InstOp.CAPTURE:
                case Inst.InstOp.NOP:
                    break;     // skip

                default:
                    done = true;
                    break;
                }

                if (done)
                {
                    break;
                }
                pc = i.@out;
            }

            return(flag);
        }
示例#2
0
文件: Machine.cs 项目: kaby76/re2cs
        // add() adds an entry to |q| for |pc|, unless the |q| already has such an
        // entry.  It also recursively adds an entry for all instructions reachable
        // from |pc| by following empty-width conditions satisfied by |cond|.  |pos|
        // gives the current position in the input.  |cond| is a bitmask of EMPTY_*
        // flags.
        private Thread add(Queue q, int pc, int pos, int[] cap, int cond, Thread t)
        {
            if (pc == 0)
            {
                return(t);
            }

            if (q.contains(pc))
            {
                return(t);
            }

            int  d    = q.add(pc);
            Inst inst = prog.inst[pc];

            switch (inst.op)
            {
            default:
                throw new IllegalStateException("unhandled");

            case Inst.InstOp.FAIL:
                break;     // nothing

            case Inst.InstOp.ALT:
            case Inst.InstOp.ALT_MATCH:
                t = add(q, inst.@out, pos, cap, cond, t);
                t = add(q, inst.arg, pos, cap, cond, t);
                break;

            case Inst.InstOp.EMPTY_WIDTH:
                if ((inst.arg & ~cond) == 0)
                {
                    t = add(q, inst.@out, pos, cap, cond, t);
                }

                break;

            case Inst.InstOp.NOP:
                t = add(q, inst.@out, pos, cap, cond, t);
                break;

            case Inst.InstOp.CAPTURE:
                if (inst.arg < ncap)
                {
                    int opos = cap[inst.arg];
                    cap[inst.arg] = pos;
                    add(q, inst.@out, pos, cap, cond, null);
                    cap[inst.arg] = opos;
                }
                else
                {
                    t = add(q, inst.@out, pos, cap, cond, t);
                }

                break;

            case Inst.InstOp.MATCH:
            case Inst.InstOp.RUNE:
            case Inst.InstOp.RUNE1:
            case Inst.InstOp.RUNE_ANY:
            case Inst.InstOp.RUNE_ANY_NOT_NL:
                if (t == null)
                {
                    t = alloc(inst);
                }
                else
                {
                    t.inst = inst;
                }

                if (ncap > 0 && t.cap != cap)
                {
                    System.Array.Copy(cap, 0, t.cap, 0, ncap);
                }

                q.denseThreads[d] = t;
                t = null;
                break;
            }

            return(t);
        }
示例#3
0
文件: Machine.cs 项目: kaby76/re2cs
        // step() executes one step of the machine, running each of the threads
        // on |runq| and appending new threads to |nextq|.
        // The step processes the rune |c| (which may be -1 for EOF),
        // which starts at position |pos| and ends at |nextPos|.
        // |nextCond| gives the setting for the EMPTY_* flags after |c|.
        // |anchor| is the anchoring flag and |atEnd| signals if we are at the end of
        // the input string.
        private void step(
            Queue runq,
            Queue nextq,
            int pos,
            int nextPos,
            int c,
            int nextCond,
            int anchor,
            bool atEnd)
        {
            bool longest = re2.longest;

            for (int j = 0; j < runq.size; ++j)
            {
                Thread t = runq.denseThreads[j];
                if (t == null)
                {
                    continue;
                }

                if (longest && matched && ncap > 0 && matchcap[0] < t.cap[0])
                {
                    free(t);
                    continue;
                }

                Inst i      = t.inst;
                bool do_add = false;
                switch (i.op)
                {
                case Inst.InstOp.MATCH:
                    if (anchor == RE2.ANCHOR_BOTH && !atEnd)
                    {
                        // Don't match if we anchor at both start and end and those
                        // expectations aren't met.
                        break;
                    }

                    if (ncap > 0 && (!longest || !matched || matchcap[1] < pos))
                    {
                        t.cap[1] = pos;
                        System.Array.Copy(t.cap, 0, matchcap, 0, ncap);
                    }

                    if (!longest)
                    {
                        free(runq, j + 1);
                    }

                    matched = true;
                    break;

                case Inst.InstOp.RUNE:
                    do_add = i.matchRune(c);
                    break;

                case Inst.InstOp.RUNE1:
                    do_add = c == i.runes[0];
                    break;

                case Inst.InstOp.RUNE_ANY:
                    do_add = true;
                    break;

                case Inst.InstOp.RUNE_ANY_NOT_NL:
                    do_add = c != '\n';
                    break;

                default:
                    throw new IllegalStateException("bad inst");
                }

                if (do_add)
                {
                    t = add(nextq, i.@out, nextPos, t.cap, nextCond, t);
                }

                if (t != null)
                {
                    free(t);
                    runq.denseThreads[j] = null;
                }
            }

            runq.clear();
        }