Lemon update 2009-11-03 13:02:26 on branch trunk

- Adjust the lemon implementation so that it always computes the same PDA regardless of qsort() implementation on the host platform. In other words, make all sorts in lemon stable. (user: drh)
This commit is contained in:
Randy Heit 2016-03-20 09:30:44 -05:00
parent 288f01a0c2
commit cafbc8b50a

View file

@ -374,6 +374,9 @@ struct action *ap2;
if( rc==0 && ap1->type==REDUCE ){ if( rc==0 && ap1->type==REDUCE ){
rc = ap1->x.rp->index - ap2->x.rp->index; rc = ap1->x.rp->index - ap2->x.rp->index;
} }
if( rc==0 ){
rc = ap2 - ap1;
}
return rc; return rc;
} }
@ -1591,7 +1594,7 @@ static void *merge(void *a,void *b,int (*cmp)(),size_t offset)
}else if( b==0 ){ }else if( b==0 ){
head = a; head = a;
}else{ }else{
if( (*cmp)(a,b)<0 ){ if( (*cmp)(a,b)<=0 ){
ptr = a; ptr = a;
a = NEXT(a); a = NEXT(a);
}else{ }else{
@ -1600,7 +1603,7 @@ static void *merge(void *a,void *b,int (*cmp)(),size_t offset)
} }
head = ptr; head = ptr;
while( a && b ){ while( a && b ){
if( (*cmp)(a,b)<0 ){ if( (*cmp)(a,b)<=0 ){
NEXT(ptr) = a; NEXT(ptr) = a;
ptr = a; ptr = a;
a = NEXT(a); a = NEXT(a);
@ -1649,7 +1652,7 @@ static void *msort(void *list,void *next,int (*cmp)())
set[i] = ep; set[i] = ep;
} }
ep = 0; ep = 0;
for(i=0; i<LISTSIZE; i++) if( set[i] ) ep = merge(ep,set[i],cmp,offset); for(i=0; i<LISTSIZE; i++) if( set[i] ) ep = merge(set[i],ep,cmp,offset);
return ep; return ep;
} }
/************************ From the file "option.c" **************************/ /************************ From the file "option.c" **************************/
@ -3560,6 +3563,7 @@ struct axset {
struct state *stp; /* A pointer to a state */ struct state *stp; /* A pointer to a state */
int isTkn; /* True to use tokens. False for non-terminals */ int isTkn; /* True to use tokens. False for non-terminals */
int nAction; /* Number of actions */ int nAction; /* Number of actions */
int iOrder; /* Original order of action sets */
}; };
/* /*
@ -3568,7 +3572,13 @@ struct axset {
static int axset_compare(const void *a, const void *b){ static int axset_compare(const void *a, const void *b){
struct axset *p1 = (struct axset*)a; struct axset *p1 = (struct axset*)a;
struct axset *p2 = (struct axset*)b; struct axset *p2 = (struct axset*)b;
return p2->nAction - p1->nAction; int c;
c = p2->nAction - p1->nAction;
if( c==0 ){
c = p2->iOrder - p1->iOrder;
}
assert( c!=0 || p1==p2 );
return c;
} }
/* /*
@ -3728,6 +3738,7 @@ int mhflag; /* Output in makeheaders format if true */
** action table to a minimum, the heuristic of placing the largest action ** action table to a minimum, the heuristic of placing the largest action
** sets first is used. ** sets first is used.
*/ */
for(i=0; i<lemp->nstate*2; i++) ax[i].iOrder = i;
qsort(ax, lemp->nstate*2, sizeof(ax[0]), axset_compare); qsort(ax, lemp->nstate*2, sizeof(ax[0]), axset_compare);
pActtab = acttab_alloc(); pActtab = acttab_alloc();
for(i=0; i<lemp->nstate*2 && ax[i].nAction>0; i++){ for(i=0; i<lemp->nstate*2 && ax[i].nAction>0; i++){
@ -4145,7 +4156,11 @@ static int stateResortCompare(const void *a, const void *b){
n = pB->nNtAct - pA->nNtAct; n = pB->nNtAct - pA->nNtAct;
if( n==0 ){ if( n==0 ){
n = pB->nTknAct - pA->nTknAct; n = pB->nTknAct - pA->nTknAct;
if( n==0 ){
n = pB->statenum - pA->statenum;
} }
}
assert( n!=0 );
return n; return n;
} }
@ -4449,6 +4464,7 @@ char *x;
int Symbolcmpp(struct symbol **a, struct symbol **b){ int Symbolcmpp(struct symbol **a, struct symbol **b){
int i1 = (**a).index + 10000000*((**a).name[0]>'Z'); int i1 = (**a).index + 10000000*((**a).name[0]>'Z');
int i2 = (**b).index + 10000000*((**b).name[0]>'Z'); int i2 = (**b).index + 10000000*((**b).name[0]>'Z');
assert( i1!=i2 || strcmp((**a).name,(**b).name)==0 );
return i1-i2; return i1-i2;
} }