/* Copyright (c) 1990 The Regents of the University of California. */ /* All rights reserved. */
/* This code is derived from software contributed to Berkeley by */ /* Vern Paxson. */
/* The United States Government has rights in this work pursuant */ /* to contract no. DE-AC03-76SF00098 between the United States */ /* Department of Energy and the University of California. */
/* This file is part of flex. */
/* Redistribution and use in source and binary forms, with or without */ /* modification, are permitted provided that the following conditions */ /* are met: */
/* 1. Redistributions of source code must retain the above copyright */ /* notice, this list of conditions and the following disclaimer. */ /* 2. Redistributions in binary form must reproduce the above copyright */ /* notice, this list of conditions and the following disclaimer in the */ /* documentation and/or other materials provided with the distribution. */
/* Neither the name of the University nor the names of its contributors */ /* may be used to endorse or promote products derived from this software */ /* without specific prior written permission. */
/* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR */ /* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED */ /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR */ /* PURPOSE. */
#include"flexdef.h"
/* declarations for functions that have forward references */
void mkentry PROTO ((int *, int, int, int, int)); void mkprot PROTO ((int[], int, int)); void mktemplate PROTO ((int[], int, int)); void mv2front PROTO ((int)); int tbldiff PROTO ((int[], int, int[]));
void bldtbl (state, statenum, totaltrans, comstate, comfreq) int state[], statenum, totaltrans, comstate, comfreq;
{ int extptr, extrct[2][CSIZE + 1]; int mindiff, minprot, i, d;
/* If extptr is 0 then the first array of extrct holds the result *ofthe"bestdifference"todate,whichisthosetransitions *whichoccurin"state"butnotintheprotowhich,todate, *hasthefewestdifferencesbetweenitselfand"state".If *extptris1thenthesecondarrayofextrctholdthebest *difference.Thetwoarraysaretoggledbetweensothatthe *bestdifferencetodatecanbekeptaroundandalsoadifference *justcreatedbycheckingagainstacandidate"best"proto.
*/
extptr = 0;
/* If the state has too few out-transitions, don't bother trying to *compactitstables.
*/
if (checkcom) { /* Find first proto which has the same "comstate". */ for (i = firstprot; i != NIL; i = protnext[i]) if (protcomst[i] == comstate) {
minprot = i;
mindiff = tbldiff (state, minprot,
extrct[extptr]); break;
}
}
else { /* Since we've decided that the most common destination *outof"state"doesnotoccurwithahighenough *frequency,wesetthe"comstate"tozero,assuring *thatifthisstateisenteredintotheprotolist, *itwillnotbeconsideredatemplate.
*/
comstate = 0;
/* We now have the first interesting proto in "minprot". If *itmatcheswithinthetolerancessetforthefirstproto, *wedon'twanttobotherscanningtherestoftheprotolist *toseeifwehaveanyotherreasonablematches.
*/
if (mindiff * 100 >
totaltrans * FIRST_MATCH_DIFF_PERCENTAGE) { /* Not a good enough match. Scan the rest of the *protos.
*/ for (i = minprot; i != NIL; i = protnext[i]) {
d = tbldiff (state, i, extrct[1 - extptr]); if (d < mindiff) {
extptr = 1 - extptr;
mindiff = d;
minprot = i;
}
}
}
/* Check if the proto we've decided on as our best bet is close *enoughtothestatewewanttomatchtobeusable.
*/
if (mindiff * 100 >
totaltrans * ACCEPTABLE_DIFF_PERCENTAGE) { /* No good. If the state is homogeneous enough, *wemakeatemplateoutofit.Otherwise,we *makeaproto.
*/
/* Since mkprot added a new proto to the proto queue, *it'spossiblethat"minprot"isnolongeronthe *protoqueue(ifithappenedtohavebeenthelast *entry,itwouldhavebeenbumpedoff).Ifit's *notthere,thenthenewprototookitsphysical *place(thoughlogicallythenewprotoisatthe *beginningofthequeue),sointhatcasethe *followingcallwilldonothing.
*/
void cmptmps ()
{ int tmpstorage[CSIZE + 1]; int *tmp = tmpstorage, i, j; int totaltrans, trans;
peakpairs = numtemps * numecs + tblend;
if (usemecs) { /* Create equivalence classes based on data gathered on *templatetransitions.
*/
nummecs = cre8ecs (tecfwd, tecbck, numecs);
}
else
nummecs = numecs;
while (lastdfa + numtemps + 1 >= current_max_dfas)
increase_max_dfas ();
/* Loop through each template. */
for (i = 1; i <= numtemps; ++i) { /* Number of non-jam transitions out of this template. */
totaltrans = 0;
for (j = 1; j <= numecs; ++j) {
trans = tnxt[numecs * i + j];
if (usemecs) { /* The absolute value of tecbck is the *meta-equivalenceclassofagiven *equivalenceclass,assetupbycre8ecs().
*/ if (tecbck[j] > 0) {
tmp[tecbck[j]] = trans;
if (trans > 0)
++totaltrans;
}
}
else {
tmp[j] = trans;
if (trans > 0)
++totaltrans;
}
}
/* It is assumed (in a rather subtle way) in the skeleton *thatifwe'reusingmeta-equivalenceclasses,thedef[] *entryforalltemplatesisthejamtemplate,i.e., *templatesneverdefaulttoothernon-jamtableentries *(e.g.,anothertemplate)
*/
/* Leave room for the jam-state after the last real state. */
mkentry (tmp, nummecs, lastdfa + i + 1, JAMSTATE,
totaltrans);
}
}
/* expand_nxt_chk - expand the next check arrays */
void expand_nxt_chk ()
{ int old_max = current_max_xpairs;
/* find_table_space - finds a space in the table for a state to be placed * *synopsis *int*state,numtrans,block_start; *intfind_table_space(); * *block_start=find_table_space(state,numtrans); * *Stateisthestatetobeaddedtothefullspeedtransitiontable. *Numtransisthenumberofout-transitionsforthestate. * *find_table_space()returnsthepositionofthestartofthefirstblock(in *chk)abletoaccommodatethestate * *Indeterminingifastatewillorwillnotfit,find_table_space()musttake *intoaccountthefactthatanend-of-bufferstatewillbeaddedat[0], *andanactionnumberwillbeaddedin[-1].
*/
int find_table_space (state, numtrans) int *state, numtrans;
{ /* Firstfree is the position of the first possible occurrence of two *consecutiveunusedrecordsinthechkandnxtarrays.
*/ int i; int *state_ptr, *chk_ptr; int *ptr_to_last_entry_in_state;
/* If there are too many out-transitions, put the state at the end of *nxtandchk.
*/ if (numtrans > MAX_XTIONS_FULL_INTERIOR_FIT) { /* If table is empty, return the first available spot in *chk/nxt,whichshouldbe1.
*/ if (tblend < 2) return1;
/* Start searching for table space near the end of *chk/nxtarrays.
*/
i = tblend - numecs;
}
else /* Start searching for table space from the beginning *(skippingonlytheelementswhichwilldefinitelynot *holdthenewstate).
*/
i = firstfree;
while (1) { /* loops until a space is found */ while (i + numecs >= current_max_xpairs)
expand_nxt_chk ();
/* Loops until space for end-of-buffer and action number *arefound.
*/ while (1) { /* Check for action number space. */ if (chk[i - 1] == 0) { /* Check for end-of-buffer space. */ if (chk[i] == 0) break;
else /* Since i != 0, there is no use *checkingtoseeif(++i)-1==0, *becausethat'sthesameasi==0, *soweskipaspace.
*/
i += 2;
}
else
++i;
while (i + numecs >= current_max_xpairs)
expand_nxt_chk ();
}
/* If we started search from the beginning, store the new *firstfreeforthenextcalloffind_table_space().
*/ if (numtrans <= MAX_XTIONS_FULL_INTERIOR_FIT)
firstfree = i + 1;
/* Check to see if all elements in chk (and therefore nxt) *thatareneededforthenewstatehavenotyetbeentaken.
*/
if (usemecs) { /* Set up doubly-linked meta-equivalence classes; these *aresetsofequivalenceclasseswhichallhaveidentical *transitionsoutofTEMPLATES.
*/
tecbck[1] = NIL;
for (i = 2; i <= numecs; ++i) {
tecbck[i] = i - 1;
tecfwd[i - 1] = i;
}
tecfwd[numecs] = NIL;
}
}
/* mkdeftbl - make the default, "jam" table entries */
void mkdeftbl ()
{ int i;
jamstate = lastdfa + 1;
++tblend; /* room for transition on end-of-buffer character */
while (tblend + numecs >= current_max_xpairs)
expand_nxt_chk ();
void mkentry (state, numchars, statenum, deflink, totaltrans) int *state; int numchars, statenum, deflink, totaltrans;
{ int minec, maxec, i, baseaddr; int tblbase, tbllast;
if (totaltrans == 0) { /* there are no out-transitions */ if (deflink == JAMSTATE)
base[statenum] = JAMSTATE; else
base[statenum] = 0;
def[statenum] = deflink; return;
}
for (minec = 1; minec <= numchars; ++minec) { if (state[minec] != SAME_TRANS) if (state[minec] != 0 || deflink != JAMSTATE) break;
}
if (totaltrans == 1) { /* There's only one out-transition. Save it for later to fill *inholesinthetables.
*/
stack1 (statenum, minec, state[minec], deflink); return;
}
for (maxec = numchars; maxec > 0; --maxec) { if (state[maxec] != SAME_TRANS) if (state[maxec] != 0 || deflink != JAMSTATE) break;
}
/* Whether we try to fit the state table in the middle of the table *entrieswehavealreadygenerated,orifwejusttakethestate *tableattheendofthenxt/chktables,wemustmakesurethatwe *haveavalidbaseaddress(i.e.,non-negative).Notethat *negativebaseaddressesdangerousatrun-time(becauseindexing *thenxtarraywithoneandalow-valuedcharacterwillaccess *memorybeforethestartofthearray.
*/
/* Find the first transition of state that we need to worry about. */ if (totaltrans * 100 <= numchars * INTERIOR_FIT_PERCENTAGE) { /* Attempt to squeeze it into the middle of the tables. */
baseaddr = firstfree;
while (baseaddr < minec) { /* Using baseaddr would result in a negative base *addressbelow;findthenextfreeslot.
*/ for (++baseaddr; chk[baseaddr] != 0; ++baseaddr) ;
}
if (firstfree >= current_max_xpairs)
expand_nxt_chk ();
}
}
/* mkprot - create new proto entry */
void mkprot (state, statenum, comstate) int state[], statenum, comstate;
{ int i, slot, tblbase;
if (++numprots >= MSP || numecs * numprots >= PROT_SAVE_SIZE) { /* Gotta make room for the new proto by dropping last entry in *thequeue.
*/
slot = lastprot;
lastprot = protprev[lastprot];
protnext[lastprot] = NIL;
}
/* place_state - place a state into full speed transition table * *Stateisthestatenum'thstate.Itisindexedbyequivalenceclassand *givesthenumberofthestatetoenterforagivenequivalenceclass. *Transnumisthenumberofout-transitionsforthestate.
*/
void place_state (state, statenum, transnum) int *state, statenum, transnum;
{ int i; int *state_ptr; int position = find_table_space (state, transnum);
/* "base" is the table of start positions. */
base[statenum] = position;
/* Put in action number marker; this non-zero number makes sure that *find_table_space()knowsthatthispositioninchk/nxtistaken *andshouldnotbeusedforanotheracceptingnumberinanother *state.
*/
chk[position - 1] = 1;
/* Put in end-of-buffer marker; this is for the same purposes as *above.
*/
chk[position] = 1;
/* Place the state into chk and nxt. */
state_ptr = &state[1];
for (i = 1; i <= numecs; ++i, ++state_ptr) if (*state_ptr != 0) {
chk[position + i] = i;
nxt[position + i] = *state_ptr;
}
if (position + numecs > tblend)
tblend = position + numecs;
}
/* stack1 - save states with only one out-transition to be processed later * *Ifthere'sroomforanotherstateonthe"one-transition"stack,the *stateispushedontoit,tobeprocessedlaterbymk1tbl.Ifthere's *noroom,weprocessthesuckerrightnow.
*/
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Angebot
Hier finden Sie eine Liste der Produkte des Unternehmens