src/main/java/com/basistech/tclre/Compiler.java
private void repeat(State lp, State rp, int m, int n) throws RegexException {
        final int rm = reduce(m);
        final int rn = reduce(n);
        State s;
        State s2;

        switch (pair(rm, rn)) {
        // pair(0, 0)
        case 0:     /* empty string */
            // never get here; other code optimizes this out.
            delsub(nfa, lp, rp);
            nfa.emptyarc(lp, rp);
            break;
        //case PAIR(0, 1):      /* do as x| */
        case 1:
            nfa.emptyarc(lp, rp);
            break;
        //case PAIR(0, SOME):       /* do as x{1,n}| */
        case SOME:
            repeat(lp, rp, 1, n);
            nfa.emptyarc(lp, rp);
            break;
        //case PAIR(0, INF):        /* loop x around */
        case INF:
            s = nfa.newstate();
            nfa.moveouts(lp, s);
            nfa.moveins(rp, s);
            nfa.emptyarc(lp, s);
            nfa.emptyarc(s, rp);
            break;
        //case PAIR(1, 1):      /* no action required */
        case 4 * 1 + 1:
            break;
        //case PAIR(1, SOME):       /* do as x{0,n-1}x = (x{1,n-1}|)x */
        case 4 * 1 + SOME:
            s = nfa.newstate();
            nfa.moveouts(lp, s);
            nfa.dupnfa(s, rp, lp, s);
            repeat(lp, s, 1, n - 1);
            nfa.emptyarc(lp, s);
            break;
        //case PAIR(1, INF):        /* add loopback arc */
        case 4 * 1 + INF:
            s = nfa.newstate();
            s2 = nfa.newstate();
            nfa.moveouts(lp, s);
            nfa.moveins(rp, s2);
            nfa.emptyarc(lp, s);
            nfa.emptyarc(s2, rp);
            nfa.emptyarc(s2, s);
            break;
        //case PAIR(SOME, SOME):        /* do as x{m-1,n-1}x */
        case 4 * SOME + SOME:
            s = nfa.newstate();
            nfa.moveouts(lp, s);
            nfa.dupnfa(s, rp, lp, s);
            repeat(lp, s, m - 1, n - 1);
            break;
        //case PAIR(SOME, INF):     /* do as x{m-1,}x */
        case 4 * SOME + INF:
            s = nfa.newstate();
            nfa.moveouts(lp, s);
            nfa.dupnfa(s, rp, lp, s);
            repeat(lp, s, m - 1, n);
            break;
        default:
            throw new RuntimeException("Impossible quantification");
        }
    }
private void repeat(State lp, State rp, int m, int n) throws RegexException {
        final int rm = reduce(m);
        final int rn = reduce(n);
        State s;
        State s2;

        switch (pair(rm, rn)) {
        // pair(0, 0)
        case 0:     /* empty string */
            // never get here; other code optimizes this out.
            delsub(nfa, lp, rp);
            nfa.emptyarc(lp, rp);
            break;
        //case PAIR(0, 1):      /* do as x| */
        case 1:
            nfa.emptyarc(lp, rp);
            break;
        //case PAIR(0, SOME):       /* do as x{1,n}| */
        case SOME:
            repeat(lp, rp, 1, n);
            nfa.emptyarc(lp, rp);
            break;
        //case PAIR(0, INF):        /* loop x around */
        case INF:
            s = nfa.newstate();
            nfa.moveouts(lp, s);
            nfa.moveins(rp, s);
            nfa.emptyarc(lp, s);
            nfa.emptyarc(s, rp);
            break;
        //case PAIR(1, 1):      /* no action required */
        case 4 * 1 + 1:
            break;
        //case PAIR(1, SOME):       /* do as x{0,n-1}x = (x{1,n-1}|)x */
        case 4 * 1 + SOME:
            s = nfa.newstate();
            nfa.moveouts(lp, s);
            nfa.dupnfa(s, rp, lp, s);
            repeat(lp, s, 1, n - 1);
            nfa.emptyarc(lp, s);
            break;
        //case PAIR(1, INF):        /* add loopback arc */
        case 4 * 1 + INF:
            s = nfa.newstate();
            s2 = nfa.newstate();
            nfa.moveouts(lp, s);
            nfa.moveins(rp, s2);
            nfa.emptyarc(lp, s);
            nfa.emptyarc(s2, rp);
            nfa.emptyarc(s2, s);
            break;
        //case PAIR(SOME, SOME):        /* do as x{m-1,n-1}x */
        case 4 * SOME + SOME:
            s = nfa.newstate();
            nfa.moveouts(lp, s);
            nfa.dupnfa(s, rp, lp, s);
            repeat(lp, s, m - 1, n - 1);
            break;
        //case PAIR(SOME, INF):     /* do as x{m-1,}x */
        case 4 * SOME + INF:
            s = nfa.newstate();
            nfa.moveouts(lp, s);
            nfa.dupnfa(s, rp, lp, s);
            repeat(lp, s, m - 1, n);
            break;
        default:
            throw new RuntimeException("Impossible quantification");
        }
    }
private void repeat ( State lp , State rp , int m , int n ) throws RegexException { final int rm = reduce ( m ) ; final int rn = reduce ( n ) ; State s ; State s2 ; switch ( pair ( rm , rn ) ) { // pair(0, 0) case 0 : /* empty string */ // never get here; other code optimizes this out. delsub ( nfa , lp , rp ) ; nfa . emptyarc ( lp , rp ) ; break ; //case PAIR(0, 1):      /* do as x| */ case 1 : nfa . emptyarc ( lp , rp ) ; break ; //case PAIR(0, SOME):       /* do as x{1,n}| */ case SOME : repeat ( lp , rp , 1 , n ) ; nfa . emptyarc ( lp , rp ) ; break ; //case PAIR(0, INF):        /* loop x around */ case INF : s = nfa . newstate ( ) ; nfa . moveouts ( lp , s ) ; nfa . moveins ( rp , s ) ; nfa . emptyarc ( lp , s ) ; nfa . emptyarc ( s , rp ) ; break ; //case PAIR(1, 1):      /* no action required */ case 4 * 1 + 1 : break ; //case PAIR(1, SOME):       /* do as x{0,n-1}x = (x{1,n-1}|)x */ case 4 * 1 + SOME : s = nfa . newstate ( ) ; nfa . moveouts ( lp , s ) ; nfa . dupnfa ( s , rp , lp , s ) ; repeat ( lp , s , 1 , n - 1 ) ; nfa . emptyarc ( lp , s ) ; break ; //case PAIR(1, INF):        /* add loopback arc */ case 4 * 1 + INF : s = nfa . newstate ( ) ; s2 = nfa . newstate ( ) ; nfa . moveouts ( lp , s ) ; nfa . moveins ( rp , s2 ) ; nfa . emptyarc ( lp , s ) ; nfa . emptyarc ( s2 , rp ) ; nfa . emptyarc ( s2 , s ) ; break ; //case PAIR(SOME, SOME):        /* do as x{m-1,n-1}x */ case 4 * SOME + SOME : s = nfa . newstate ( ) ; nfa . moveouts ( lp , s ) ; nfa . dupnfa ( s , rp , lp , s ) ; repeat ( lp , s , m - 1 , n - 1 ) ; break ; //case PAIR(SOME, INF):     /* do as x{m-1,}x */ case 4 * SOME + INF : s = nfa . newstate ( ) ; nfa . moveouts ( lp , s ) ; nfa . dupnfa ( s , rp , lp , s ) ; repeat ( lp , s , m - 1 , n ) ; break ; default : throw new RuntimeException ( "Impossible quantification" ) ; } }
repeat - replicate subNFA for quantifiers
The duplication sequences used here are chosen carefully so that any
pointers starting out pointing into the subexpression end up pointing into
the last occurrence.  (Note that it may not be strung between the same
left and right end states, however!)  This used to be important for the
subRE tree, although the important bits are now handled by the in-line
code in parse(), and when this is called, it doesn't matter any more.
repeat - replicate subNFA for quantifiers The duplication sequences used here are chosen carefully so that any pointers starting out pointing into the subexpression end up pointing into the last occurrence . ( Note that it may not be strung between the same left and right end states however! ) This used to be important for the subRE tree although the important bits are now handled by the in - line code in parse () and when this is called it doesn t matter any more .