src/main/java/com/basistech/tclre/Nfa.java
boolean push(Arc con) throws RegexException {
        State from = con.from;
        State to = con.to;
        Arc a;
        Arc nexta;
        State s;

        if (to == from) {   /* circular constraint is pointless */
            freearc(con);
            return true;
        }
        if (0 != to.flag) {     /* can't push forward beyond end */
            return false;
        }
        if (to.nouts == 0) {    /* dead end */
            freearc(con);
            return true;
        }

    /* first, clone to state if necessary to avoid other inarcs */
        if (to.nins > 1) {
            s = newstate();

            copyouts(to, s);        /* duplicate outarcs */
            cparc(con, from, s);    /* move constraint */
            freearc(con);
            to = s;
            con = to.ins;
        }
        assert to.nins == 1;

    /* propagate the constraint into the to state's outarcs */
        for (a = to.outs; a != null; a = nexta) {
            nexta = a.outchain;
            switch (combine(con, a)) {
            case INCOMPATIBLE:  /* destroy the arc */
                freearc(a);
                break;
            case SATISFIED:     /* no action needed */
                break;
            case COMPATIBLE:    /* swap the two arcs, more or less */
                s = newstate();
                cparc(con, s, a.to);    /* anticipate move */
                cparc(a, from, s);
                freearc(a);
                break;
            default:
                throw new RegexException("REG_ASSERT");
            }
        }

    /* remaining outarcs, if any, incorporate the constraint */
        moveouts(to, from);
        dropstate(to);      /* will free the constraint */
        return true;
    }
boolean push(Arc con) throws RegexException {
        State from = con.from;
        State to = con.to;
        Arc a;
        Arc nexta;
        State s;

        if (to == from) {   /* circular constraint is pointless */
            freearc(con);
            return true;
        }
        if (0 != to.flag) {     /* can't push forward beyond end */
            return false;
        }
        if (to.nouts == 0) {    /* dead end */
            freearc(con);
            return true;
        }

    /* first, clone to state if necessary to avoid other inarcs */
        if (to.nins > 1) {
            s = newstate();

            copyouts(to, s);        /* duplicate outarcs */
            cparc(con, from, s);    /* move constraint */
            freearc(con);
            to = s;
            con = to.ins;
        }
        assert to.nins == 1;

    /* propagate the constraint into the to state's outarcs */
        for (a = to.outs; a != null; a = nexta) {
            nexta = a.outchain;
            switch (combine(con, a)) {
            case INCOMPATIBLE:  /* destroy the arc */
                freearc(a);
                break;
            case SATISFIED:     /* no action needed */
                break;
            case COMPATIBLE:    /* swap the two arcs, more or less */
                s = newstate();
                cparc(con, s, a.to);    /* anticipate move */
                cparc(a, from, s);
                freearc(a);
                break;
            default:
                throw new RegexException("REG_ASSERT");
            }
        }

    /* remaining outarcs, if any, incorporate the constraint */
        moveouts(to, from);
        dropstate(to);      /* will free the constraint */
        return true;
    }
boolean push ( Arc con ) throws RegexException { State from = con . from ; State to = con . to ; Arc a ; Arc nexta ; State s ; if ( to == from ) { /* circular constraint is pointless */ freearc ( con ) ; return true ; } if ( 0 != to . flag ) { /* can't push forward beyond end */ return false ; } if ( to . nouts == 0 ) { /* dead end */ freearc ( con ) ; return true ; } /* first, clone to state if necessary to avoid other inarcs */ if ( to . nins > 1 ) { s = newstate ( ) ; copyouts ( to , s ) ; /* duplicate outarcs */ cparc ( con , from , s ) ; /* move constraint */ freearc ( con ) ; to = s ; con = to . ins ; } assert to . nins == 1 ; /* propagate the constraint into the to state's outarcs */ for ( a = to . outs ; a != null ; a = nexta ) { nexta = a . outchain ; switch ( combine ( con , a ) ) { case INCOMPATIBLE : /* destroy the arc */ freearc ( a ) ; break ; case SATISFIED : /* no action needed */ break ; case COMPATIBLE : /* swap the two arcs, more or less */ s = newstate ( ) ; cparc ( con , s , a . to ) ; /* anticipate move */ cparc ( a , from , s ) ; freearc ( a ) ; break ; default : throw new RegexException ( "REG_ASSERT" ) ; } } /* remaining outarcs, if any, incorporate the constraint */ moveouts ( to , from ) ; dropstate ( to ) ; /* will free the constraint */ return true ; }
push - push a forward constraint forward past its destination state
A significant property of this function is that it deletes at most
one state -- the constraint's to state -- and only if the constraint
was that state's last inarc.
push - push a forward constraint forward past its destination state A significant property of this function is that it deletes at most one state -- the constraint s to state -- and only if the constraint was that state s last inarc .