int dupmachine(int mach) { int i, init, state_offset; int state = 0; int last = lastst[mach]; for ( i = firstst[mach]; i <= last; ++i ) { state = mkstate( transchar[i] ); if ( trans1[i] != NO_TRANSITION ) { mkxtion( finalst[state], trans1[i] + state - i ); if ( transchar[i] == SYM_EPSILON && trans2[i] != NO_TRANSITION ) mkxtion( finalst[state], trans2[i] + state - i ); } accptnum[state] = accptnum[i]; } if ( state == 0 ) flexfatal( "empty machine in dupmachine()" ); state_offset = state - i + 1; init = mach + state_offset; firstst[init] = firstst[mach] + state_offset; finalst[init] = finalst[mach] + state_offset; lastst[init] = lastst[mach] + state_offset; return ( init ); }
int mkor(int first, int second) { int eps, orend; if ( first == NIL ) return ( second ); else if ( second == NIL ) return ( first ); else { /* see comment in mkopt() about why we can't use the first state * of "first" or "second" if they satisfy "FREE_EPSILON" */ eps = mkstate( SYM_EPSILON ); first = link_machines( eps, first ); mkxtion( first, second ); if ( SUPER_FREE_EPSILON(finalst[first]) && accptnum[finalst[first]] == NIL ) { orend = finalst[first]; mkxtion( finalst[second], orend ); } else if ( SUPER_FREE_EPSILON(finalst[second]) && accptnum[finalst[second]] == NIL ) { orend = finalst[second]; mkxtion( finalst[first], orend ); } else { eps = mkstate( SYM_EPSILON ); first = link_machines( first, eps ); orend = finalst[first]; mkxtion( finalst[second], orend ); } } finalst[first] = orend; return ( first ); }
/* mkposcl - convert a machine into a positive closure * * synopsis * new = mkposcl( state ); * * new - a machine matching the positive closure of "state" */ int mkposcl(int state) { int eps; if (SUPER_FREE_EPSILON(finalst[state])) { mkxtion(finalst[state], state); return state; } else { eps = mkstate(SYM_EPSILON); mkxtion(eps, state); return link_machines(state, eps); } }
int mkbranch(int first, int second) { int eps; if ( first == NO_TRANSITION ) return ( second ); else if ( second == NO_TRANSITION ) return ( first ); eps = mkstate( SYM_EPSILON ); mkxtion( eps, first ); mkxtion( eps, second ); return ( eps ); }
int link_machines(int first, int last) { if ( first == NIL ) return ( last ); else if ( last == NIL ) return ( first ); else { mkxtion( finalst[first], last ); finalst[first] = finalst[last]; lastst[first] = max( lastst[first], lastst[last] ); firstst[first] = min( firstst[first], firstst[last] ); return ( first ); } }
/* link_machines - connect two machines together * * synopsis * * new = link_machines( first, last ); * * new - a machine constructed by connecting first to last * first - the machine whose successor is to be last * last - the machine whose predecessor is to be first * * note: this routine concatenates the machine first with the machine * last to produce a machine new which will pattern-match first first * and then last, and will fail if either of the sub-patterns fails. * FIRST is set to new by the operation. last is unmolested. */ int link_machines(int first, int last) { if (first == NIL) return last; else if (last == NIL) return first; else { mkxtion(finalst[first], last); finalst[first] = finalst[last]; lastst[first] = MAX(lastst[first], lastst[last]); firstst[first] = MIN(firstst[first], firstst[last]); return first; } }
int mkopt(int mach) { int eps; if ( ! SUPER_FREE_EPSILON(finalst[mach]) ) { eps = mkstate( SYM_EPSILON ); mach = link_machines( mach, eps ); } /* can't skimp on the following if FREE_EPSILON(mach) is true because * some state interior to "mach" might point back to the beginning * for a closure */ eps = mkstate( SYM_EPSILON ); mach = link_machines( eps, mach ); mkxtion( mach, finalst[mach] ); return ( mach ); }