int mkstate(int sym) { if ( ++lastnfa >= current_mns ) { if ( (current_mns += MNS_INCREMENT) >= MAXIMUM_MNS ) lerrif( "input rules are too complicated (>= %d NFA states)", current_mns ); ++num_reallocs; firstst = reallocate_integer_array( firstst, current_mns ); lastst = reallocate_integer_array( lastst, current_mns ); finalst = reallocate_integer_array( finalst, current_mns ); transchar = reallocate_integer_array( transchar, current_mns ); trans1 = reallocate_integer_array( trans1, current_mns ); trans2 = reallocate_integer_array( trans2, current_mns ); accptnum = reallocate_integer_array( accptnum, current_mns ); assoc_rule = reallocate_integer_array( assoc_rule, current_mns ); state_type = reallocate_integer_array( state_type, current_mns ); } firstst[lastnfa] = lastnfa; finalst[lastnfa] = lastnfa; lastst[lastnfa] = lastnfa; transchar[lastnfa] = sym; trans1[lastnfa] = NO_TRANSITION; trans2[lastnfa] = NO_TRANSITION; accptnum[lastnfa] = NIL; assoc_rule[lastnfa] = num_rules; state_type[lastnfa] = current_state_type; /* fix up equivalence classes base on this transition. Note that any * character which has its own transition gets its own equivalence class. * Thus only characters which are only in character classes have a chance * at being in the same equivalence class. E.g. "a|b" puts 'a' and 'b' * into two different equivalence classes. "[ab]" puts them in the same * equivalence class (barring other differences elsewhere in the input). */ if ( sym < 0 ) { /* we don't have to update the equivalence classes since that was * already done when the ccl was created for the first time */ } else if ( sym == SYM_EPSILON ) ++numeps; else { if ( useecs ) /* map NUL's to csize */ mkechar( sym ? sym : csize, nextecm, ecgroup ); } return ( lastnfa ); }
void sympartition (int ds[], int numstates, int symlist[], int duplist[]) { int tch, i, j, k, ns, dupfwd[CSIZE + 1], lenccl, cclp, ich; /* Partitioning is done by creating equivalence classes for those * characters which have out-transitions from the given state. Thus * we are really creating equivalence classes of equivalence classes. */ for (i = 1; i <= numecs; ++i) { /* initialize equivalence class list */ duplist[i] = i - 1; dupfwd[i] = i + 1; } duplist[1] = NIL; dupfwd[numecs] = NIL; for (i = 1; i <= numstates; ++i) { ns = ds[i]; tch = transchar[ns]; if (tch != SYM_EPSILON) { if (tch < -lastccl || tch >= csize) { flexfatal (_ ("bad transition character detected in sympartition()")); } if (tch >= 0) { /* character transition */ int ec = ecgroup[tch]; mkechar (ec, dupfwd, duplist); symlist[ec] = 1; } else { /* character class */ tch = -tch; lenccl = ccllen[tch]; cclp = cclmap[tch]; mkeccl (ccltbl + cclp, lenccl, dupfwd, duplist, numecs, NUL_ec); if (cclng[tch]) { j = 0; for (k = 0; k < lenccl; ++k) { ich = ccltbl[cclp + k]; if (ich == 0) ich = NUL_ec; for (++j; j < ich; ++j) symlist[j] = 1; } for (++j; j <= numecs; ++j) symlist[j] = 1; } else for (k = 0; k < lenccl; ++k) { ich = ccltbl[cclp + k]; if (ich == 0) ich = NUL_ec; symlist[ich] = 1; } } } } }